Fauna v10 .NET/C# Driver 0.2.0-beta
 
Loading...
Searching...
No Matches
DynamicSerializer.cs
Go to the documentation of this file.
1using Fauna.Mapping;
2using Fauna.Types;
3
4namespace Fauna.Serialization;
5
6internal class DynamicSerializer : BaseSerializer<object?>
7{
8 public static DynamicSerializer Singleton { get; } = new();
9
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;
15
16 private DynamicSerializer()
17 {
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>();
23 }
24
25 public override object? Deserialize(MappingContext context, ref Utf8FaunaReader reader) =>
26 reader.CurrentTokenType switch
27 {
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}"),
44 };
45
53 public override void Serialize(MappingContext ctx, Utf8FaunaWriter w, object? o)
54 {
55 SerializeValueInternal(ctx, w, o);
56 }
57
58 private void SerializeValueInternal(MappingContext ctx, Utf8FaunaWriter w, object? o)
59 {
60 switch (o)
61 {
62 case null:
63 w.WriteNullValue();
64 break;
65 case byte v:
66 w.WriteIntValue(v);
67 break;
68 case sbyte v:
69 w.WriteIntValue(v);
70 break;
71 case ushort v:
72 w.WriteIntValue(v);
73 break;
74 case short v:
75 w.WriteIntValue(v);
76 break;
77 case int v:
78 w.WriteIntValue(v);
79 break;
80 case uint v:
81 w.WriteLongValue(v);
82 break;
83 case long v:
84 w.WriteLongValue(v);
85 break;
86 case float v:
87 w.WriteDoubleValue(v);
88 break;
89 case double v:
90 w.WriteDoubleValue(v);
91 break;
92 case decimal:
93 throw new SerializationException("Decimals are unsupported due to potential loss of precision.");
94 case bool v:
95 w.WriteBooleanValue(v);
96 break;
97 case string v:
98 w.WriteStringValue(v);
99 break;
100 case Module v:
101 w.WriteModuleValue(v);
102 break;
103 case DateTime v:
104 w.WriteTimeValue(v);
105 break;
106 case DateTimeOffset v:
107 w.WriteTimeValue(v);
108 break;
109 case DateOnly v:
110 w.WriteDateValue(v);
111 break;
112 case Ref doc:
113 SerializeDocumentRefInternal(w, doc.Id, doc.Collection);
114 break;
115 case Document doc:
116 SerializeDocumentRefInternal(w, doc.Id, doc.Collection);
117 break;
119 switch (doc)
120 {
122 SerializeDocumentRefInternal(w, d.Id, d.Collection);
123 break;
125 SerializeDocumentRefInternal(w, d.Value!.Id, d.Value!.Collection);
126 break;
127 }
128 break;
129 case NullableDocument<Ref> doc:
130 switch (doc)
131 {
132 case NullDocument<Ref> d:
133 SerializeDocumentRefInternal(w, d.Id, d.Collection);
134 break;
136 SerializeDocumentRefInternal(w, d.Value!.Id, d.Value!.Collection);
137 break;
138 }
139 break;
140 case NamedRef doc:
141 SerializeNamedDocumentRefInternal(w, doc.Name, doc.Collection);
142 break;
143 case NamedDocument doc:
144 SerializeNamedDocumentRefInternal(w, doc.Name, doc.Collection);
145 break;
147 switch (doc)
148 {
150 SerializeNamedDocumentRefInternal(w, d.Id, d.Collection);
151 break;
153 SerializeNamedDocumentRefInternal(w, d.Value!.Name, d.Value!.Collection);
154 break;
155 }
156 break;
158 switch (doc)
159 {
161 SerializeNamedDocumentRefInternal(w, d.Id, d.Collection);
162 break;
164 SerializeNamedDocumentRefInternal(w, d.Value!.Name, d.Value!.Collection);
165 break;
166 }
167 break;
168 case Dictionary<string, object> d:
169 SerializeIDictionaryInternal(ctx, w, d);
170 break;
171 case IEnumerable<object> e:
172 w.WriteStartArray();
173 foreach (var obj in e)
174 {
175 SerializeValueInternal(ctx, w, obj);
176 }
177 w.WriteEndArray();
178 break;
179 default:
180 SerializeClassInternal(ctx, w, o);
181 break;
182 }
183 }
184
185
186 private void SerializeDocumentRefInternal(Utf8FaunaWriter writer, string id, Module coll)
187 {
188 writer.WriteStartRef();
189 writer.WriteString("id", id);
190 writer.WriteModule("coll", coll);
191 writer.WriteEndRef();
192 }
193
194 private void SerializeNamedDocumentRefInternal(Utf8FaunaWriter writer, string name, Module coll)
195 {
196 writer.WriteStartRef();
197 writer.WriteString("name", name);
198 writer.WriteModule("coll", coll);
199 writer.WriteEndRef();
200 }
201
202
203 private void SerializeIDictionaryInternal<T>(MappingContext ctx, Utf8FaunaWriter writer, IDictionary<string, T> d)
204 {
205 var shouldEscape = Serializer.Tags.Overlaps(d.Keys);
206 if (shouldEscape) writer.WriteStartEscapedObject(); else writer.WriteStartObject();
207 foreach (var (key, value) in d)
208 {
209 writer.WriteFieldName(key);
210 Serialize(ctx, writer, value);
211 }
212 if (shouldEscape) writer.WriteEndEscapedObject(); else writer.WriteEndObject();
213 }
214
215 private void SerializeClassInternal(MappingContext ctx, Utf8FaunaWriter writer, object obj)
216 {
217 var t = obj.GetType();
218 var mapping = ctx.GetInfo(t);
219 var shouldEscape = mapping.ShouldEscapeObject;
220
221 if (shouldEscape) writer.WriteStartEscapedObject(); else writer.WriteStartObject();
222 foreach (var field in mapping.Fields)
223 {
224 writer.WriteFieldName(field.Name!);
225 var v = field.Property.GetValue(obj);
226 SerializeValueInternal(ctx, writer, v);
227 }
228 if (shouldEscape) writer.WriteEndEscapedObject(); else writer.WriteEndObject();
229 }
230}
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 document.
Definition Document.cs:7
Represents a module, a singleton object grouping related functionalities. Modules are serialized as @...
Definition Module.cs:8
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...
Definition NamedRef.cs:8
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.
Definition Ref.cs:7