1using System.Diagnostics;
 
    8internal interface IClassDocumentSerializer : ISerializer
 
   10    public object DeserializeDocument(
MappingContext context, 
string? 
id, 
string? name, ref Utf8FaunaReader reader);
 
   13internal class ClassSerializer<T> : BaseSerializer<T>, IClassDocumentSerializer
 
   15    private const string IdField = 
"id";
 
   16    private const string NameField = 
"name";
 
   18    private readonly 
bool _isDocument;
 
   22        Debug.Assert(info.
Type == typeof(T));
 
   26    public ClassSerializer(
MappingInfo info, 
bool isDocument)
 
   28        Debug.Assert(info.
Type == typeof(T));
 
   30        _isDocument = isDocument;
 
   33    public object DeserializeDocument(
MappingContext context, 
string? 
id, 
string? name, ref Utf8FaunaReader reader)
 
   35        object instance = CreateInstance();
 
   36        if (
id is not 
null) TrySetId(instance, 
id);
 
   37        if (name is not 
null) TrySetName(instance, name);
 
   38        SetFields(instance, context, ref reader, 
TokenType.EndDocument);
 
   42    public override T Deserialize(
MappingContext context, ref Utf8FaunaReader reader)
 
   44        var endToken = reader.CurrentTokenType 
switch 
   46            TokenType.StartDocument => 
TokenType.EndDocument,
 
   47            TokenType.StartObject => 
TokenType.EndObject,
 
   49            var other => 
throw UnexpectedToken(other),
 
   60            while (reader.Read() && reader.CurrentTokenType != 
TokenType.EndRef)
 
   62                if (reader.CurrentTokenType != 
TokenType.FieldName)
 
   63                    throw new SerializationException(
 
   64                        $
"Unexpected token while deserializing into DocumentRef: {reader.CurrentTokenType}");
 
   66                string fieldName = reader.GetString()!;
 
   71                        id = reader.GetString();
 
   74                        name = reader.GetString();
 
   77                        coll = reader.GetModule();
 
   80                        cause = reader.GetString();
 
   83                        exists = reader.GetBoolean();
 
   88            if ((
id != 
null || name != 
null) && coll != 
null && exists)
 
   90                throw new SerializationException(
"Cannot deserialize refs into classes.");
 
   93            throw new NullDocumentException((
id ?? name)!, coll!, cause!);
 
   96        object instance = CreateInstance();
 
   97        SetFields(instance, context, ref reader, endToken);
 
  101    public override void Serialize(
MappingContext ctx, Utf8FaunaWriter w, 
object? o)
 
  103        var skipFields = 
new HashSet<string>();
 
  109                if (fi.
Name.ToLowerInvariant() == 
"id" && fi.
Property.GetValue(o) is 
null) skipFields.Add(
"id");
 
  110                if (fi.
Name.ToLowerInvariant() == 
"coll" && fi.
Property.GetValue(o) is 
null) skipFields.Add(
"coll");
 
  111                if (fi.
Name.ToLowerInvariant() == 
"ts" && fi.
Property.GetValue(o) is 
null) skipFields.Add(
"ts");
 
  115        SerializeInternal(ctx, w, o, skipFields);
 
  118    private static void SerializeInternal(
MappingContext ctx, Utf8FaunaWriter w, 
object? o, IReadOnlySet<string> skipFields)
 
  128        bool shouldEscape = info.ShouldEscapeObject;
 
  130        if (shouldEscape) w.WriteStartEscapedObject(); 
else w.WriteStartObject();
 
  131        foreach (var field 
in info.Fields)
 
  133            if (skipFields.Contains(field.Name.ToLowerInvariant())) 
continue;
 
  135            w.WriteFieldName(field.Name);
 
  136            object? v = field.Property.GetValue(o);
 
  137            field.Serializer.Serialize(ctx, w, v);
 
  139        if (shouldEscape) w.WriteEndEscapedObject(); 
else w.WriteEndObject();
 
  142    private object CreateInstance() => Activator.CreateInstance(_info.Type)!;
 
  144    private void SetFields(
object instance, 
MappingContext context, ref Utf8FaunaReader reader, 
TokenType endToken)
 
  146        while (reader.Read() && reader.CurrentTokenType != endToken)
 
  148            if (reader.CurrentTokenType != 
TokenType.FieldName)
 
  149                throw UnexpectedToken(reader.CurrentTokenType);
 
  151            string fieldName = reader.GetString()!;
 
  154            if (fieldName == IdField && reader.CurrentTokenType == 
TokenType.String)
 
  156                TrySetId(instance, reader.GetString()!);
 
  158            else if (fieldName == NameField && reader.CurrentTokenType == 
TokenType.String)
 
  160                TrySetName(instance, reader.GetString()!);
 
  162            else if (_info.FieldsByName.TryGetValue(fieldName, out var field))
 
  164                field.Property.SetValue(instance, field.Serializer.Deserialize(context, ref reader));
 
  173    private void TrySetId(
object instance, 
string id)
 
  175        if (!_info.FieldsByName.TryGetValue(IdField, out var field))
 
  180        if (field.Type == typeof(
long))
 
  182            field.Property.SetValue(instance, 
long.Parse(
id));
 
  184        else if (field.Type == typeof(
string))
 
  186            field.Property.SetValue(instance, 
id);
 
  194    private void TrySetName(
object instance, 
string name)
 
  196        if (_info.FieldsByName.TryGetValue(NameField, out var field))
 
  198            if (field.Type == typeof(
string))
 
  200                field.Property.SetValue(instance, name);
 
  209    private new SerializationException UnexpectedToken(
TokenType tokenType) =>
 
  210        new($
"Unexpected token while deserializing into class {_info.Type.Name}: {tokenType}");
 
A class that encapsulates the field mapping, serialization, and deserialization of a particular field...
PropertyInfo Property
The property info of an associated class.
string Name
The name of the field.
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.
A class that encapsulates the class mapping, serialization, and deserialization of a Fauna object,...
Type Type
The associated type.
Represents a module, a singleton object grouping related functionalities. Modules are serialized as @...
TokenType
Enumerates the types of tokens used in Fauna serialization.