namespace ZB.MOM.WW.CBDD.Bson.Schema; public class BsonField { /// /// Gets the field name. /// public required string Name { get; init; } /// /// Gets the field BSON type. /// public BsonType Type { get; init; } /// /// Gets a value indicating whether the field is nullable. /// public bool IsNullable { get; init; } /// /// Gets the nested schema when this field is a document. /// public BsonSchema? NestedSchema { get; init; } /// /// Gets the array item type when this field is an array. /// public BsonType? ArrayItemType { get; init; } /// /// Writes this field definition to BSON. /// /// The BSON writer. public void ToBson(ref BsonSpanWriter writer) { int size = writer.BeginDocument(); writer.WriteString("n", Name); writer.WriteInt32("t", (int)Type); writer.WriteBoolean("b", IsNullable); if (NestedSchema != null) { writer.WriteElementHeader(BsonType.Document, "s"); NestedSchema.ToBson(ref writer); } if (ArrayItemType != null) writer.WriteInt32("a", (int)ArrayItemType.Value); writer.EndDocument(size); } /// /// Reads a field definition from BSON. /// /// The BSON reader. /// The deserialized field. public static BsonField FromBson(ref BsonSpanReader reader) { reader.ReadInt32(); // Read doc size var name = ""; var type = BsonType.Null; var isNullable = false; BsonSchema? nestedSchema = null; BsonType? arrayItemType = null; while (reader.Remaining > 1) { var btype = reader.ReadBsonType(); if (btype == BsonType.EndOfDocument) break; string key = reader.ReadElementHeader(); switch (key) { case "n": name = reader.ReadString(); break; case "t": type = (BsonType)reader.ReadInt32(); break; case "b": isNullable = reader.ReadBoolean(); break; case "s": nestedSchema = BsonSchema.FromBson(ref reader); break; case "a": arrayItemType = (BsonType)reader.ReadInt32(); break; default: reader.SkipValue(btype); break; } } return new BsonField { Name = name, Type = type, IsNullable = isNullable, NestedSchema = nestedSchema, ArrayItemType = arrayItemType }; } /// /// Computes a hash representing the field definition. /// /// The computed hash value. public long GetHash() { var hash = new HashCode(); hash.Add(Name); hash.Add((int)Type); hash.Add(IsNullable); hash.Add(ArrayItemType); if (NestedSchema != null) hash.Add(NestedSchema.GetHash()); return hash.ToHashCode(); } /// /// Determines whether this field is equal to another field. /// /// The other field. /// if the fields are equal; otherwise, . public bool Equals(BsonField? other) { if (other == null) return false; return GetHash() == other.GetHash(); } /// public override bool Equals(object? obj) { return Equals(obj as BsonField); } /// public override int GetHashCode() { return (int)GetHash(); } }