Safe Haskell | None |
---|---|
Language | Haskell2010 |
Bond is an extensible framework for working with schematized data. It is suitable for scenarios ranging from service communications to Big Data storage and processing.
Bond defines a rich type system and schema versioning rules which allow forward and backward compatibility.
Core bond library is published on GitHub at https://github.com/Microsoft/bond/.
- class BondProto t where
- bondRead :: BondStruct a => t -> ByteString -> Either String a
- bondWrite :: BondStruct a => t -> a -> Either String ByteString
- bondReadWithSchema :: t -> StructSchema -> ByteString -> Either String Struct
- bondWriteWithSchema :: t -> StructSchema -> Struct -> Either String ByteString
- bondMarshal :: BondStruct a => t -> a -> Either String ByteString
- bondMarshalWithSchema :: t -> StructSchema -> Struct -> Either String ByteString
- protoSig :: t -> ByteString
- class BondProto t => BondTaggedProto t where
- bondReadTagged :: t -> ByteString -> Either String Struct
- bondWriteTagged :: t -> Struct -> Either String ByteString
- bondMarshalTagged :: t -> Struct -> Either String ByteString
- data CompactBinaryV1Proto = CompactBinaryV1Proto
- data CompactBinaryProto = CompactBinaryProto
- data FastBinaryProto = FastBinaryProto
- data SimpleBinaryV1Proto = SimpleBinaryV1Proto
- data SimpleBinaryProto = SimpleBinaryProto
- data JsonProto = JsonProto
- data Bonded a
- getValue :: BondStruct a => Bonded a -> Either String a
- putValue :: a -> Bonded a
- castValue :: BondStruct b => Bonded a -> Either String b
- marshalValue :: (BondProto t, BondStruct a) => t -> a -> Either String (Bonded b)
- data BondedException = BondedException String
- class BondType a => BondStruct a where
- getSchema :: Proxy a -> StructSchema
- class BondEnum a where
- assembleSchema :: StructSchema -> SchemaDef
- checkStructSchema :: MonadError String m => StructSchema -> Struct -> m Struct
- defaultStruct :: StructSchema -> Struct
- parseSchema :: SchemaDef -> Either String StructSchema
- data Struct = Struct {}
- data Value
- = BOOL Bool
- | INT8 Int8
- | INT16 Int16
- | INT32 Int32
- | INT64 Int64
- | UINT8 Word8
- | UINT16 Word16
- | UINT32 Word32
- | UINT64 Word64
- | FLOAT Float
- | DOUBLE Double
- | STRING Utf8
- | WSTRING Utf16
- | STRUCT Struct
- | LIST BondDataType [Value]
- | SET BondDataType [Value]
- | MAP BondDataType BondDataType [(Value, Value)]
- | BONDED (Bonded Struct)
- bondUnmarshal :: BondStruct a => ByteString -> Either String a
- bondUnmarshalWithSchema :: StructSchema -> ByteString -> Either String Struct
- bondUnmarshalTagged :: ByteString -> Either String Struct
- class IsString a => EncodedString a where
- newtype Ordinal = Ordinal Word16
- defaultValue :: Default a => a
- newtype BondDataType = BondDataType Int32
- bT_BOOL :: BondDataType
- bT_UINT8 :: BondDataType
- bT_UINT16 :: BondDataType
- bT_UINT32 :: BondDataType
- bT_UINT64 :: BondDataType
- bT_FLOAT :: BondDataType
- bT_DOUBLE :: BondDataType
- bT_STRING :: BondDataType
- bT_STRUCT :: BondDataType
- bT_LIST :: BondDataType
- bT_SET :: BondDataType
- bT_MAP :: BondDataType
- bT_INT8 :: BondDataType
- bT_INT16 :: BondDataType
- bT_INT32 :: BondDataType
- bT_INT64 :: BondDataType
- bT_WSTRING :: BondDataType
- data SchemaDef
Example
Let's use following schema.bond
IDL file:
namespace my.test struct my_struct { 10: int32 m_int; 20: string m_str = "some string"; }
Code generation requires hbc
program from bond-haskell-compiler
package:
hbc schema.bond
This creates file My.Test.My_struct.hs
. Note that case conversions are
performed to create syntactically correct Haskell code.
-- create structure and set m_int to 5: let struct = defaultValue { m_int = 5 } -- serializestruct
with FastBinary protocol let Right binstream = bondWrite FastBinaryProto struct -- parsebinstream
using runtime schema let Right rtstruct = bondReadWithSchema FastBinaryProto (getSchema (Proxy :: Proxy My_struct)) binstream
class BondProto t where Source
Typeclass for Bond serialization protocols.
bondRead :: BondStruct a => t -> ByteString -> Either String a Source
Deserialize structure from stream.
bondWrite :: BondStruct a => t -> a -> Either String ByteString Source
Serialize structure to stream.
bondReadWithSchema :: t -> StructSchema -> ByteString -> Either String Struct Source
Deserialize structure from stream using provided schema.
bondWriteWithSchema :: t -> StructSchema -> Struct -> Either String ByteString Source
Serialize structure to stream using provided schema.
bondMarshal :: BondStruct a => t -> a -> Either String ByteString Source
Serialize structure to stream and add protocol header. See bondUnmarshal
for deserialization.
bondMarshalWithSchema :: t -> StructSchema -> Struct -> Either String ByteString Source
Serialize structure to stream using provided schema and add protocol header. See bondUnmarshalWithSchema
for deserialization.
protoSig :: t -> ByteString Source
Get protocol header.
class BondProto t => BondTaggedProto t where Source
Typeclass for tagged Bond serialization protocols. Such protocols support schemaless operations.
bondReadTagged :: t -> ByteString -> Either String Struct Source
Deserialize structure from stream without schema.
bondWriteTagged :: t -> Struct -> Either String ByteString Source
Serialize structure to stream without schema.
bondMarshalTagged :: t -> Struct -> Either String ByteString Source
Serialize structure to stream without schema and add protocol header. See bondUnmarshalTagged
for deserialization.
Supported protocols
data CompactBinaryV1Proto Source
A binary, tagged protocol using variable integer encoding and compact field header.
data CompactBinaryProto Source
A binary, tagged protocol using variable integer encoding and compact field header. Version 2 of Compact Binary adds length prefix for structs. This enables deserialization of bonded<T> and skipping of unknown struct fields in constant time.
data FastBinaryProto Source
A binary, tagged protocol similar to CompactBinaryProto
but optimized for deserialization speed rather than payload compactness.
data SimpleBinaryV1Proto Source
A binary, untagged protocol which is a good choice for storage scenarios as it offers potential for big saving on payload size. Because Simple is an untagged protocol, it requires that the payload schema is available during deserialization.
data SimpleBinaryProto Source
A binary, untagged protocol which is a good choice for storage scenarios as it offers potential for big saving on payload size. Because Simple is an untagged protocol, it requires that the payload schema is available during deserialization. Version 2 of Simple Protocol uses variable integer encoding for string and container lengths, resulting in more compact payload.
The output is a standard JSON and is a very good choice for interoperating with other systems or generating human readable payload. Because payload doesn't include field ordinals, it is treated as untagged protocol.
bonded<T>
bonded<T> value
BondedStream ByteString | Marshalled stream |
BondedObject a | Deserialized value |
getValue :: BondStruct a => Bonded a -> Either String a Source
Extract value from Bonded
using compile-type schema
castValue :: BondStruct b => Bonded a -> Either String b Source
Extract value from Bonded
using compile-type schema for other type.
This may be useful for casting values to child structs.
User is responsible for schema compatibility.
marshalValue :: (BondProto t, BondStruct a) => t -> a -> Either String (Bonded b) Source
Marshal struct to the bonded<T> field. There is no checks for schema compatibility, caveat emptor.
data BondedException Source
BondedException is thrown when attempt to deserialize bonded field for comparison fails. To handle such cases in the pure code explicitly decode all bonded fields before comparing structures.
Runtime-schema operations
Generic applications may need to work with Bond schemas unknown
at compile-time. In order to address such scenarios Bond defines a
type SchemaDef
to represent schemas in stoorage
and transfer.
Haskell library uses StructSchema
internally for performance
reasons and provides conversion functions.
class BondType a => BondStruct a where Source
Bond top-level structure, can be de/serialized on its own.
getSchema :: Proxy a -> StructSchema Source
Obtain struct schema.
Bond enumeration class containing utility functions.
assembleSchema :: StructSchema -> SchemaDef Source
Convert internal schema representation to SchemaDef
for storage or transfer.
checkStructSchema :: MonadError String m => StructSchema -> Struct -> m Struct Source
Verify that Struct
matches StructSchema
and is internally consistent.
defaultStruct :: StructSchema -> Struct Source
Create minimal valid Struct
representing given schema
parseSchema :: SchemaDef -> Either String StructSchema Source
Convert SchemaDef
to internal schema representation.
Representation of bond structure used in runtime-schema operations.
Representation of bond serializable type used in runtime-schema operations.
Marshalling
Since Bond supports multiple serialization protocols, application endpoints either have to agree on a particular protocol, or include protocol metadata in the payload. Marshaling APIs provide the standard way to do the latter, by automatically adding a payload header with the protocol identifier and version.
See bondMarshal
, bondMarshalWithSchema
and bondMarshalTagged
for serialization.
bondUnmarshal :: BondStruct a => ByteString -> Either String a Source
Deserialize structure from stream, finding protocol from stream header.
bondUnmarshalWithSchema :: StructSchema -> ByteString -> Either String Struct Source
Deserialize structure from stream with provided schema, finding protocol from stream header.
bondUnmarshalTagged :: ByteString -> Either String Struct Source
Deserialize structure from stream without schema, finding protocol from stream header.
Misc
class IsString a => EncodedString a where Source
Bond structure field ordinal.
defaultValue :: Default a => a Source
Get default value for specified type.
Reexported from generated code
newtype BondDataType Source