Skip to content

Commit

Permalink
Support Set
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsenko committed Jul 30, 2024
1 parent a6a7dd1 commit 63e10ea
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
9 changes: 9 additions & 0 deletions packages/ejson/lib/src/decoding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const _commonDecoders = {
Object: _decodeAny,
Iterable: _decodeArray,
List: _decodeArray,
Set: _decodeSet,
bool: _decodeBool,
DateTime: _decodeDate,
Defined: _decodeDefined,
Expand Down Expand Up @@ -116,6 +117,7 @@ dynamic _decodeAny(EJsonValue ejson) {
{'\$binary': {'base64': _, 'subType': '04'}} => _decodeUuid(ejson),
{'\$binary': _} => _decodeBinary(ejson),
List<dynamic> _ => _decodeArray<dynamic>(ejson),
Set<dynamic> _ => _decodeSet<dynamic>(ejson),
Map<dynamic, dynamic> _ => _tryDecodeCustomIfAllowed(ejson) ?? _decodeDocument<String, dynamic>(ejson), // other maps goes last!!
_ => raiseInvalidEJson<dynamic>(ejson),
};
Expand All @@ -142,6 +144,13 @@ List<T> _decodeArray<T>(EJsonValue ejson) {
};
}

Set<T> _decodeSet<T>(EJsonValue ejson) {
return switch (ejson) {
Iterable<dynamic> i => i.map((ejson) => fromEJson<T>(ejson)).toSet(),
_ => raiseInvalidEJson(ejson),
};
}

bool _decodeBool(EJsonValue ejson) {
return switch (ejson) {
bool b => b,
Expand Down
2 changes: 1 addition & 1 deletion packages/ejson/lib/src/encoding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ EJsonValue _encodeAny(Object? value) {
int i => _encodeInt(i),
BsonKey k => _encodeKey(k),
Uint8List b => _encodeBinary(b, subtype: '00'),
Iterable<dynamic> l => _encodeArray(l),
Iterable<dynamic> l => _encodeArray(l), // handles List and Set as well
Map<dynamic, dynamic> m => _encodeDocument(m),
ObjectId o => _encodeObjectId(o),
String s => _encodeString(s),
Expand Down
12 changes: 12 additions & 0 deletions packages/ejson/test/ejson_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ void main() {
_invalidTestCase<BsonKey>();
_invalidTestCase<List>();
_invalidTestCase<List<int>>();
_invalidTestCase<Set>();
_invalidTestCase<Set<int>>();
_invalidTestCase<Map>([]);
_invalidTestCase<Map<int, int>>([]);
_invalidTestCase<Null>();
Expand Down Expand Up @@ -157,6 +159,16 @@ void main() {
]
: [1, 2, 3],
);
_testCase(
{1, 2, 3},
canonical
? {
{'\$numberInt': '1'},
{'\$numberInt': '2'},
{'\$numberInt': '3'},
}
: {1, 2, 3},
);
_testCase(
[1, 1.1],
canonical
Expand Down
34 changes: 34 additions & 0 deletions packages/realm_dart/test/serialization_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,38 @@ void main() {
expect(toEJson(d), {'\$numberDecimal': '+42E+0'});
expect(fromEJson<Decimal128>({'\$numberDecimal': '42'}), d);
});

test('Set<RealmValue> on RealmObject', () {
final oid = ObjectId();
final realm = Realm(Configuration.inMemory([ObjectWithRealmValue.schema]));
final o = realm.write(() => realm.add(ObjectWithRealmValue(oid, setOfAny: {RealmValue.from(42), RealmValue.from('42')})));
expect(o.setOfAny, {RealmValue.from(42), RealmValue.from('42')});
final serialized = toEJsonString(o);
expect(serialized, '{"_id":{"\$oid":"$oid"},"differentiator":null,"oneAny":null,"manyAny":[],"dictOfAny":{},"setOfAny":[{"\$numberInt":"42"},"42"]}');
final deserialized = fromEJsonString<ObjectWithRealmValue>(serialized);
// deserialized is unmanaged, so will never compare equal, but we can test properties
expect(deserialized.id, o.id);
expect(deserialized.setOfAny, o.setOfAny);
});

test('Set on RealmObject', () {
final realm = Realm(Configuration.inMemory([AllCollections.schema]));
final o = realm.write(() => realm.add(AllCollections(intSet: {1, 2, 3})));
expect(o.intSet, {1, 2, 3});
final deserialized = fromEJsonString<AllCollections>(toEJsonString(o));
// deserialized is unmanaged, so will never compare equal, but we can test properties
expect(deserialized.intSet, o.intSet);
});

test('Set in RealmValue', () {
final rv = RealmValue.from({1, 2, 3}); // constructed from a list of ints
expect(rv.value, [RealmValue.from(1), RealmValue.from(2), RealmValue.from(3)]); // but becomes a list RealmValues
expect(rv.toEJson(), [
// and serializes as a list of EJson
{'\$numberInt': '1'},
{'\$numberInt': '2'},
{'\$numberInt': '3'},
]);
// expect(rv.as<Set<int>>(), {1, 2, 3}); // doesn't work because the set is a list of RealmValues. Should we support this?
});
}

0 comments on commit 63e10ea

Please sign in to comment.