Fauna .NET Driver 0.1.0-beta
 
Loading...
Searching...
No Matches
Serializer.cs
Go to the documentation of this file.
1using Fauna.Mapping;
4
5namespace Fauna.Serialization;
6
10public static partial class Serializer
11{
12
13 internal static readonly HashSet<string> Tags = new()
14 {
15 "@int", "@long", "@double", "@date", "@time", "@mod", "@ref", "@doc", "@set", "@object"
16 };
17
25 public static void Serialize(MappingContext ctx, Utf8FaunaWriter w, object? o)
26 {
27 SerializeValueInternal(ctx, w, o);
28 }
29
30 private static void SerializeValueInternal(MappingContext ctx, Utf8FaunaWriter w, object? o, FaunaType? ty = null)
31 {
32 if (ty != null)
33 {
34 if (o is null) throw new ArgumentNullException(nameof(o));
35
36 switch (ty)
37 {
38 case FaunaType.Int:
39 if (o is byte or sbyte or short or ushort or int)
40 {
41 var int32 = Convert.ToInt32(o);
42 w.WriteIntValue(int32);
43 }
44 else
45 {
46 throw new SerializationException($"Unsupported Int conversion. Provided value must be a byte, sbyte, short, ushort, or int but was a {o.GetType()}");
47 }
48 break;
49 case FaunaType.Long:
50 if (o is byte or sbyte or short or ushort or int or uint or long)
51 {
52 var int64 = Convert.ToInt64(o);
53 w.WriteLongValue(int64);
54 }
55 else
56 {
57 throw new SerializationException($"Unsupported Long conversion. Provided value must be a byte, sbyte, short, ushort, int, uint, or long but was a {o.GetType()}");
58 }
59 break;
60 case FaunaType.Double:
61 switch (o)
62 {
63 case float or double or short or int or long:
64 {
65 var dub = Convert.ToDouble(o);
66 w.WriteDoubleValue(dub);
67 break;
68 }
69 default:
70 throw new SerializationException($"Unsupported Double conversion. Provided value must be a short, int, long, float, or double, but was a {o.GetType()}");
71 }
72 break;
73 case FaunaType.String:
74 w.WriteStringValue(o.ToString() ?? string.Empty);
75 break;
76 case FaunaType.Date:
77 switch (o)
78 {
79 case DateTime v:
80 w.WriteDateValue(v);
81 break;
82 case DateOnly v:
83 w.WriteDateValue(v);
84 break;
85 case DateTimeOffset v:
86 w.WriteDateValue(v);
87 break;
88 default:
89 throw new SerializationException($"Unsupported Date conversion. Provided value must be a DateTime, DateTimeOffset, or DateOnly but was a {o.GetType()}");
90 }
91 break;
92 case FaunaType.Time:
93 switch (o)
94 {
95 case DateTime v:
96 w.WriteTimeValue(v);
97 break;
98 case DateTimeOffset v:
99 w.WriteTimeValue(v);
100 break;
101 default:
102 throw new SerializationException($"Unsupported Time conversion. Provided value must be a DateTime or DateTimeOffset but was a {o.GetType()}");
103 }
104 break;
105 case FaunaType.Boolean:
106 if (o is bool b)
107 {
108 w.WriteBooleanValue(b);
109 }
110 else
111 {
112 throw new SerializationException($"Unsupported Boolean conversion. Provided value must be a bool but was a {o.GetType()}");
113 }
114 break;
115 default:
116 throw new ArgumentOutOfRangeException(nameof(ty), ty, null);
117 }
118 }
119 else
120 {
121 switch (o)
122 {
123 case null:
124 w.WriteNullValue();
125 break;
126 case byte v:
127 w.WriteIntValue(v);
128 break;
129 case sbyte v:
130 w.WriteIntValue(v);
131 break;
132 case ushort v:
133 w.WriteIntValue(v);
134 break;
135 case short v:
136 w.WriteIntValue(v);
137 break;
138 case int v:
139 w.WriteIntValue(v);
140 break;
141 case uint v:
142 w.WriteLongValue(v);
143 break;
144 case long v:
145 w.WriteLongValue(v);
146 break;
147 case float v:
148 w.WriteDoubleValue(v);
149 break;
150 case double v:
151 w.WriteDoubleValue(v);
152 break;
153 case decimal:
154 throw new SerializationException("Decimals are unsupported due to potential loss of precision.");
155 case bool v:
156 w.WriteBooleanValue(v);
157 break;
158 case string v:
159 w.WriteStringValue(v);
160 break;
161 case Module v:
162 w.WriteModuleValue(v);
163 break;
164 case DateTime v:
165 w.WriteTimeValue(v);
166 break;
167 case DateTimeOffset v:
168 w.WriteTimeValue(v);
169 break;
170 case DateOnly v:
171 w.WriteDateValue(v);
172 break;
173 default:
174 SerializeObjectInternal(w, o, ctx);
175 break;
176 }
177 }
178 }
179
180 private static void SerializeObjectInternal(Utf8FaunaWriter writer, object obj, MappingContext context)
181 {
182 switch (obj)
183 {
184 case Dictionary<string, object> d:
185 SerializeIDictionaryInternal(writer, d, context);
186 break;
187 case IEnumerable<object> e:
188 writer.WriteStartArray();
189 foreach (var o in e)
190 {
191 SerializeValueInternal(context, writer, o);
192 }
193 writer.WriteEndArray();
194 break;
195 default:
196 SerializeClassInternal(writer, obj, context);
197 break;
198 }
199 }
200
201 private static void SerializeIDictionaryInternal<T>(Utf8FaunaWriter writer, IDictionary<string, T> d,
202 MappingContext context)
203 {
204 var shouldEscape = Tags.Overlaps(d.Keys);
205 if (shouldEscape) writer.WriteStartEscapedObject(); else writer.WriteStartObject();
206 foreach (var (key, value) in d)
207 {
208 writer.WriteFieldName(key);
209 Serialize(context, writer, value);
210 }
211 if (shouldEscape) writer.WriteEndEscapedObject(); else writer.WriteEndObject();
212 }
213
214 private static void SerializeClassInternal(Utf8FaunaWriter writer, object obj, MappingContext context)
215 {
216 var t = obj.GetType();
217 var mapping = context.GetInfo(t);
218 var shouldEscape = mapping.ShouldEscapeObject;
219
220 if (shouldEscape) writer.WriteStartEscapedObject(); else writer.WriteStartObject();
221 foreach (var field in mapping.Fields)
222 {
223 writer.WriteFieldName(field.Name!);
224 var v = field.Property.GetValue(obj);
225 SerializeValueInternal(context, writer, v, field.FaunaTypeHint);
226 }
227 if (shouldEscape) writer.WriteEndEscapedObject(); else writer.WriteEndObject();
228 }
229}
Fauna.Types.Module Module
Definition Serializer.cs:3
MappingInfo GetInfo(Type ty)
Represents a module, a singleton object grouping related functionalities. Modules are serialized as @...
Definition Module.cs:8
FaunaType
Enumerates the different types of data that can be stored in Fauna.
Definition Attributes.cs:7
Definition Client.cs:9