6internal class DynamicSerializer : BaseSerializer<object?>
8 public static DynamicSerializer Singleton {
get; } =
new();
10 private readonly ListSerializer<object?> _list;
11 private readonly PageSerializer<object?> _page;
12 private readonly DictionarySerializer<object?> _dict;
13 private readonly DocumentSerializer<object> _doc;
14 private readonly DocumentSerializer<object> _ref;
16 private DynamicSerializer()
18 _list =
new ListSerializer<object?>(
this);
19 _page =
new PageSerializer<object?>(
this);
20 _dict =
new DictionarySerializer<object?>(
this);
21 _doc =
new DocumentSerializer<object>();
22 _ref =
new DocumentSerializer<object>();
25 public override object? Deserialize(
MappingContext context, ref Utf8FaunaReader reader) =>
26 reader.CurrentTokenType
switch
28 TokenType.StartObject => _dict.Deserialize(context, ref reader),
29 TokenType.StartArray => _list.Deserialize(context, ref reader),
30 TokenType.StartPage => _page.Deserialize(context, ref reader),
31 TokenType.StartRef => _ref.Deserialize(context, ref reader),
32 TokenType.StartDocument => _doc.Deserialize(context, ref reader),
33 TokenType.String => reader.GetString(),
34 TokenType.Int => reader.GetInt(),
35 TokenType.Long => reader.GetLong(),
36 TokenType.Double => reader.GetDouble(),
37 TokenType.Date => reader.GetDate(),
38 TokenType.Time => reader.GetTime(),
39 TokenType.True or TokenType.False => reader.GetBoolean(),
40 TokenType.Module => reader.GetModule(),
41 TokenType.Null =>
null,
42 _ =>
throw new SerializationException(
43 $
"Unexpected token while deserializing: {reader.CurrentTokenType}"),
53 public override void Serialize(
MappingContext ctx, Utf8FaunaWriter w,
object? o)
55 SerializeValueInternal(ctx, w, o);
58 private void SerializeValueInternal(
MappingContext ctx, Utf8FaunaWriter w,
object? o)
87 w.WriteDoubleValue(v);
90 w.WriteDoubleValue(v);
93 throw new SerializationException(
"Decimals are unsupported due to potential loss of precision.");
95 w.WriteBooleanValue(v);
98 w.WriteStringValue(v);
101 w.WriteModuleValue(v);
106 case DateTimeOffset v:
113 SerializeDocumentRefInternal(w, doc.Id, doc.Collection);
116 SerializeDocumentRefInternal(w, doc.Id, doc.Collection);
122 SerializeDocumentRefInternal(w, d.Id, d.Collection);
125 SerializeDocumentRefInternal(w, d.Value!.Id, d.Value!.Collection);
133 SerializeDocumentRefInternal(w, d.Id, d.Collection);
136 SerializeDocumentRefInternal(w, d.Value!.Id, d.Value!.Collection);
141 SerializeNamedDocumentRefInternal(w, doc.Name, doc.Collection);
144 SerializeNamedDocumentRefInternal(w, doc.Name, doc.Collection);
150 SerializeNamedDocumentRefInternal(w, d.Id, d.Collection);
153 SerializeNamedDocumentRefInternal(w, d.Value!.Name, d.Value!.Collection);
161 SerializeNamedDocumentRefInternal(w, d.Id, d.Collection);
164 SerializeNamedDocumentRefInternal(w, d.Value!.Name, d.Value!.Collection);
168 case Dictionary<string, object> d:
169 SerializeIDictionaryInternal(ctx, w, d);
171 case IEnumerable<object> e:
173 foreach (var obj
in e)
175 SerializeValueInternal(ctx, w, obj);
180 SerializeClassInternal(ctx, w, o);
186 private void SerializeDocumentRefInternal(Utf8FaunaWriter writer,
string id,
Module coll)
188 writer.WriteStartRef();
189 writer.WriteString(
"id",
id);
190 writer.WriteModule(
"coll", coll);
191 writer.WriteEndRef();
194 private void SerializeNamedDocumentRefInternal(Utf8FaunaWriter writer,
string name,
Module coll)
196 writer.WriteStartRef();
197 writer.WriteString(
"name", name);
198 writer.WriteModule(
"coll", coll);
199 writer.WriteEndRef();
203 private void SerializeIDictionaryInternal<T>(
MappingContext ctx, Utf8FaunaWriter writer, IDictionary<string, T> d)
205 var shouldEscape = Serializer.Tags.Overlaps(d.Keys);
206 if (shouldEscape) writer.WriteStartEscapedObject();
else writer.WriteStartObject();
207 foreach (var (key, value) in d)
209 writer.WriteFieldName(key);
210 Serialize(ctx, writer, value);
212 if (shouldEscape) writer.WriteEndEscapedObject();
else writer.WriteEndObject();
215 private void SerializeClassInternal(
MappingContext ctx, Utf8FaunaWriter writer,
object obj)
217 var t = obj.GetType();
219 var shouldEscape = mapping.ShouldEscapeObject;
221 if (shouldEscape) writer.WriteStartEscapedObject();
else writer.WriteStartObject();
222 foreach (var field
in mapping.Fields)
224 writer.WriteFieldName(field.Name!);
225 var v = field.Property.GetValue(obj);
226 SerializeValueInternal(ctx, writer, v);
228 if (shouldEscape) writer.WriteEndEscapedObject();
else writer.WriteEndObject();
A class representing the mapping context to be used during serialization and deserialization.
MappingInfo GetInfo(Type ty, string? colName=null)
Gets the MappingInfo for a given Type.
Represents a module, a singleton object grouping related functionalities. Modules are serialized as @...
Represents a document that has a "name" instead of an "id". For example, a Role document is represent...
Represents a document ref that has a "name" instead of an "id". For example, a Role document referenc...
A class wrapping a non-null document returned by Fauna.
A class representing a null document returned by Fauna.
A wrapper class that allows Document and user-defined classes to be null references.
Represents a document ref.