Fauna v10 .NET/C# Driver 1.0.0
 
Loading...
Searching...
No Matches
DynamicSerializer.cs
Go to the documentation of this file.
2using Fauna.Mapping;
3using Fauna.Types;
4
5namespace Fauna.Serialization;
6
7internal class DynamicSerializer : BaseSerializer<object?>
8{
9 public static DynamicSerializer Singleton { get; } = new();
10
11 private readonly ListSerializer<object?> _list;
12 private readonly PageSerializer<object?> _page;
13 private readonly DictionarySerializer<object?> _dict;
14 private readonly BaseRefSerializer<Dictionary<string, object>> _docref;
15
16
17 private DynamicSerializer()
18 {
19 _list = new ListSerializer<object?>(this);
20 _page = new PageSerializer<object?>(this);
21 _dict = new DictionarySerializer<object?>(this);
22 _docref = new BaseRefSerializer<Dictionary<string, object>>(_dict);
23 }
24
25 public override List<FaunaType> GetSupportedTypes() => new List<FaunaType> {
26 FaunaType.Array,
27 FaunaType.Boolean,
28 FaunaType.Bytes,
29 FaunaType.Date,
30 FaunaType.Double,
31 FaunaType.Document,
32 FaunaType.Int,
33 FaunaType.Long,
34 FaunaType.Module,
35 FaunaType.Null,
36 FaunaType.Object,
37 FaunaType.Ref,
38 FaunaType.Set,
39 FaunaType.Stream,
40 FaunaType.String,
41 FaunaType.Time
42 };
43
44 public override object? Deserialize(MappingContext ctx, ref Utf8FaunaReader reader) =>
45 reader.CurrentTokenType switch
46 {
47 TokenType.StartObject => _dict.Deserialize(ctx, ref reader),
48 TokenType.StartArray => _list.Deserialize(ctx, ref reader),
49 TokenType.StartPage => _page.Deserialize(ctx, ref reader),
50 TokenType.StartRef => _docref.Deserialize(ctx, ref reader),
51 TokenType.StartDocument => DeserializeDocumentInternal(ctx, ref reader),
52 TokenType.String => reader.GetString(),
53 TokenType.Int => reader.GetInt(),
54 TokenType.Long => reader.GetLong(),
55 TokenType.Double => reader.GetDouble(),
56 TokenType.Date => reader.GetDate(),
57 TokenType.Time => reader.GetTime(),
58 TokenType.True or TokenType.False => reader.GetBoolean(),
59 TokenType.Module => reader.GetModule(),
60 TokenType.Bytes => reader.GetBytes(),
61 TokenType.Null => null,
62 TokenType.EventSource => reader.GetEventSource(),
63 _ => throw new SerializationException(
64 $"Unexpected token while deserializing: {reader.CurrentTokenType}"),
65 };
66
67 private object DeserializeDocumentInternal(MappingContext context, ref Utf8FaunaReader reader)
68 {
69 var builder = new BaseRefBuilder<Dictionary<string, object>>();
70 while (reader.Read() && reader.CurrentTokenType != TokenType.EndDocument)
71 {
72 if (reader.CurrentTokenType != TokenType.FieldName)
73 throw new SerializationException(
74 $"Unexpected token while deserializing @doc: {reader.CurrentTokenType}");
75
76 string fieldName = reader.GetString()!;
77
78 reader.Read();
79
80 switch (fieldName)
81 {
82 // Relies on ordering for doc fields.
83 case "id":
84 builder.Id = reader.GetString();
85 break;
86 case "name":
87 builder.Name = reader.GetString();
88 break;
89 case "coll":
90 builder.Collection = reader.GetModule();
91
92 // if we encounter a mapped collection, jump to the class deserializer.
93 // NB this relies on the fact that docs on the wire always start with id and coll.
94 if (context.TryGetCollection(builder.Collection.Name, out var info) && info.ClassSerializer is IPartialDocumentSerializer ser)
95 {
96 return new BaseRefBuilder<object>
97 {
98 Id = builder.Id,
99 Name = builder.Name,
100 Collection = builder.Collection,
101 Doc = ser.DeserializeDocument(context, builder.Id, builder.Name, builder.Collection,
102 ref reader)
103 }.Build();
104 }
105
106 builder.Doc = (Dictionary<string, object>?)_dict.DeserializeDocument(context, builder.Id, builder.Name, builder.Collection, ref reader);
107 break;
108 }
109
110 // After we deserialize into a doc, we end on the EndDocument a token and do not want to read again
111 if (reader.CurrentTokenType == TokenType.EndDocument) break;
112 }
113
114 return builder.Build();
115 }
116
124 public override void Serialize(MappingContext ctx, Utf8FaunaWriter w, object? o)
125 {
126 if (o == null)
127 {
128 w.WriteNullValue();
129 return;
130 }
131
132 var ser = Serializer.Generate(ctx, o.GetType());
133 ser.Serialize(ctx, w, o);
134 }
135}
Represents error that occur during serialization and deserialization of Fauna data.
A class representing the mapping context to be used during serialization and deserialization.
bool TryGetCollection(string col, [NotNullWhen(true)] out MappingInfo? ret)
Gets the MappingInfo for a given collection name.
void Serialize(MappingContext ctx, Utf8FaunaWriter writer, object? o)
Serializes the provided object into the Utf8FaunaWriter.
new T Deserialize(MappingContext ctx, ref Utf8FaunaReader reader)
Consumes all or some of a Utf8FaunaReader and returns an instance of T .
object? ISerializer. Deserialize(MappingContext ctx, ref Utf8FaunaReader reader)
Consumes or partially consumes the provided reader and deserializes into a result.
void ISerializer. Serialize(MappingContext context, Utf8FaunaWriter writer, object? o)
Serializes the provided object onto the Utf8FaunaWriter
FaunaType
An enum representing possible Fauna types.
Definition FaunaType.cs:7
TokenType
Enumerates the types of tokens used in Fauna serialization.
Definition TokenType.cs:7