encodeFirestoreValue function

CborValue encodeFirestoreValue(
  1. Object? v
)

Encodes a document body for the native side.

Plain Dart values map to their CBOR equivalents; FirestoreValue instances become tagged items.

Implementation

CborValue encodeFirestoreValue(Object? v) {
  if (v == null) return const CborNull();
  if (v is bool) return CborBool(v);
  if (v is int) return CborInt(BigInt.from(v));
  if (v is double) return CborFloat(v);
  if (v is String) return CborString(v);
  if (v is Uint8List) return CborBytes(v);
  if (v is FirestoreTimestamp) {
    return CborList(
      [CborInt(BigInt.from(v.seconds)), CborInt(BigInt.from(v.nanoseconds))],
      tags: [FirestoreTag.timestamp],
    );
  }
  if (v is FirestoreGeoPoint) {
    return CborList(
      [CborFloat(v.latitude), CborFloat(v.longitude)],
      tags: [FirestoreTag.geoPoint],
    );
  }
  if (v is FirestoreReference) {
    return CborString(v.path, tags: [FirestoreTag.reference]);
  }
  if (v is FirestoreSentinel) {
    final payload = v._payload;
    return switch (v._tag) {
      FirestoreTag.arrayUnion || FirestoreTag.arrayRemove => CborList(
        (payload! as List<Object?>).map(encodeFirestoreValue).toList(),
        tags: [v._tag],
      ),
      // A one-element array, not a bare number: the cbor package drops tags
      // when it normalizes an integer to a small int, so a tagged bare int
      // arrives untagged and would decode as an ordinary value.
      FirestoreTag.incrementInt => CborList(
        [CborInt(BigInt.from(payload! as int))],
        tags: [v._tag],
      ),
      FirestoreTag.incrementDouble => CborList(
        [CborFloat((payload! as num).toDouble())],
        tags: [v._tag],
      ),
      _ => CborNull(tags: [v._tag]),
    };
  }
  if (v is List) return CborList(v.map(encodeFirestoreValue).toList());
  if (v is Map) {
    return CborMap({
      for (final e in v.entries)
        CborString('${e.key}'): encodeFirestoreValue(e.value),
    });
  }
  throw ArgumentError.value(v, 'value', 'no Firestore mapping for this type');
}