Module vibe.data.serialization
Generic serialization framework.
This module provides general means for implementing (de-)serialization with a standardized behavior.
Supported types
The following rules are applied in order when serializing or deserializing a certain type:
- An
enum
type is serialized as its raw value, except if@byName
is used, in which case the name of the enum value is serialized. - Any type that is specifically supported by the serializer
is directly serialized. For example, the BSON serializer
supports
BsonObjectID
directly. - Arrays and tuples (
std
) are serialized using the array serialization functions where each element is serialized again according to these rules..typecons .Tuple - Associative arrays are serialized similar to arrays. The key
type of the AA must satisfy the
isStringSerializable
trait and will always be serialized as a string. - Any
Nullable!T
will be serialized as eithernull
, or as the contained value (subject to these rules again). - Any
Typedef!T
will be serialized as if it were justT
. - Any
BitFlags!T
value will be serialized asT[]
- Types satisfying the
isPolicySerializable
trait for the suppliedPolicy
will be serialized as the value returned by the policytoRepresentation
function (again subject to these rules). - Types satisfying the
isCustomSerializable
trait will be serialized as the value returned by theirtoRepresentation
method (again subject to these rules). - Types satisfying the
isISOExtStringSerializable
trait will be serialized as a string, as returned by theirtoISOExtString
method. This causes types such asSysTime
to be serialized as strings. - Types satisfying the
isStringSinkSerializable
trait will be serialized as a string using thetoString(sink)
method.sink
can either be a delegate that takes achar
array argument, or an output range ofchar
. - Types satisfying the
isStringSerializable
trait will be serialized as a string, as returned by theirtoString
method. - Struct and class types by default will be serialized as
associative arrays, where the key is the name of the
corresponding field (can be overridden using the
@name
attribute). If the struct/class is annotated with@asArray
, it will instead be serialized as a flat array of values in the order of declaration. Null class references will be serialized asnull
. - Pointer types will be serialized as either
null
, or as the value they point to. - Built-in integers and floating point values, as well as boolean values will be converted to strings, if the serializer doesn't support them directly.
Note that no aliasing detection is performed, so that pointers, class references and arrays referencing the same memory will be serialized as multiple copies. When in turn deserializing the data, they will also end up as separate copies in memory.
Field names
By default, the field name of the serialized D type (for struct
and
class
aggregates) is represented as-is in the serialized result. To
circumvent name clashes with D's keywords, a single trailing underscore of
any field name is stipped, so that a field name of version_
results in
just "version"
as the serialized value. Names can also be freely
customized using the @name
annotation.
Associative array keys are always represented using their direct string representation.
Serializer implementation
Serializers are implemented in terms of a struct with template methods that get called by the serialization framework:
struct ExampleSerializer {
enum isSupportedValueType(T) = is(T == string) || is(T == typeof(null));
// serialization
auto getSerializedResult();
void beginWriteDocument(TypeTraits)();
void endWriteDocument(TypeTraits)();
void beginWriteDictionary(TypeTraits)(size_t length); [OR] void beginWriteDictionary(TypeTraits)();
void endWriteDictionary(TypeTraits)();
void beginWriteDictionaryEntry(ElementTypeTraits)(string name);
void endWriteDictionaryEntry(ElementTypeTraits)(string name);
void beginWriteArray(TypeTraits)(size_t length);
void endWriteArray(TypeTraits)();
void beginWriteArrayEntry(ElementTypeTraits)(size_t index);
void endWriteArrayEntry(ElementTypeTraits)(size_t index);
void writeValue(TypeTraits, T)(T value);
// deserialization
void readDictionary(TypeTraits)(scope void delegate(string) entry_callback);
void beginReadDictionaryEntry(ElementTypeTraits)(string);
void endReadDictionaryEntry(ElementTypeTraits)(string);
void readArray(TypeTraits)(scope void delegate(size_t) size_callback, scope void delegate() entry_callback);
void beginReadArrayEntry(ElementTypeTraits)(size_t index);
void endReadArrayEntry(ElementTypeTraits)(size_t index);
T readValue(TypeTraits, T)();
bool tryReadNull(TypeTraits)();
// skipValue() is optional. It will be called by the entry_callback in readDictionary
// whenever the key passed to the entry_callback cannot be found.
void skipValue();
}
The TypeTraits
type passed to the individual methods has the following members:
Type
: The original type of the field to serializeAttributes
: User defined attributes attached to the fieldPolicy
: An alias to the policy used for the serialization process
ElementTypeTraits
have the following additional members:
ContainerType
: The original type of the enclosing container typeContainerAttributes
: User defined attributes attached to the enclosing container
Functions
Name | Description |
---|---|
asArray()
|
Attribute for representing a struct/class as an array instead of an object. |
byName()
|
Attribute for forcing serialization of enum fields by name instead of by value. |
deserialize(args)
|
Deserializes and returns a serialized value. |
deserializeWithPolicy(args)
|
Deserializes and returns a serialized value, interpreting values according to Policy when possible.
|
embedNullable()
|
Makes this nullable as if it is not a nullable to the serializer. Ignores the field completely when it is null. |
ignore()
|
Attribute for marking non-serialized fields. |
name(name)
|
Attribute for overriding the field name during (de-)serialization. |
optional()
|
Attribute marking a field as optional during deserialization. |
serialize(value, args)
|
Serializes a value with the given serializer. |
serializeWithPolicy(value, args)
|
Serializes a value with the given serializer, representing values according to Policy when possible.
|
Classes
Name | Description |
---|---|
Base64ArrayPolicy
|
Uses Base64 representation for ubyte[] instead of to!string
|
Structs
Name | Description |
---|---|
AsArrayAttribute
|
User defined attribute (not intended for direct use) |
ByNameAttribute
|
User defined attribute (not intended for direct use) |
EmbedNullableIgnoreNullAttribute
|
User defined attribute (not intended for direct use) |
IgnoreAttribute
|
User defined attribute (not intended for direct use) |
NameAttribute
|
User defined attribute (not intended for direct use) |
OptionalAttribute
|
User defined attribute (not intended for direct use) |
Enums
Name | Description |
---|---|
FieldExistence
|
Templates
Name | Description |
---|---|
DefaultPolicy
|
Default policy (performs no customization). |
Manifest constants
Name | Type | Description |
---|---|---|
isCustomSerializable
|
Checks if a given type has a custom serialization representation. | |
isISOExtStringSerializable
|
Checks if a given type has an ISO extended string serialization representation. | |
isPolicySerializable
|
Checks if a given policy supports custom serialization for a given type. | |
isStringSerializable
|
Checks if a given type has a string serialization representation. | |
isStringSinkSerializable
|
Aliases
Name | Type | Description |
---|---|---|
ChainedPolicy
|
Primary
|
Chains serialization policy. |