Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions dart/packages/fory-test/lib/entity/enum_id_foo.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import 'package:fory/fory.dart';

part '../generated/enum_id_foo.g.dart';

@foryEnum
enum EnumWithIds {
@ForyEnumId(10)
A,
@ForyEnumId(20)
B,
@ForyEnumId(30)
C,
}

@foryEnum
enum EnumPartialIds {
@ForyEnumId(10)
A,
B,
@ForyEnumId(30)
C,
}

@foryEnum
enum EnumDuplicateIds {
@ForyEnumId(10)
A,
@ForyEnumId(10)
B,
@ForyEnumId(30)
C,
}
17 changes: 17 additions & 0 deletions dart/packages/fory-test/test/codegen_test/enum_codegen_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ library;

import 'package:checks/checks.dart';
import 'package:fory/fory.dart';
import 'package:fory_test/entity/enum_id_foo.dart';
import 'package:fory_test/entity/enum_foo.dart';
import 'package:test/test.dart';

Expand All @@ -31,8 +32,24 @@ void main() {
EnumSpec enumSpec = EnumSpec(EnumFoo, [EnumFoo.A, EnumFoo.B]);
EnumSpec enumSubTypeSpec =
EnumSpec(EnumSubClass, [EnumSubClass.A, EnumSubClass.B]);
EnumSpec enumWithIdsSpec = EnumSpec(
EnumWithIds,
[EnumWithIds.A, EnumWithIds.B, EnumWithIds.C],
{
10: EnumWithIds.A,
20: EnumWithIds.B,
30: EnumWithIds.C,
});
EnumSpec enumPartialIdsSpec =
EnumSpec(EnumPartialIds,[EnumPartialIds.A, EnumPartialIds.B, EnumPartialIds.C]);
EnumSpec enumDuplicateIdsSpec =
EnumSpec(EnumDuplicateIds, [EnumDuplicateIds.A, EnumDuplicateIds.B, EnumDuplicateIds.C]);

check($EnumFoo).equals(enumSpec);
check($EnumSubClass).equals(enumSubTypeSpec);
check($EnumWithIds).equals(enumWithIdsSpec);
check($EnumPartialIds).equals(enumPartialIdsSpec);
check($EnumDuplicateIds).equals(enumDuplicateIdsSpec);
});
});
}
148 changes: 148 additions & 0 deletions dart/packages/fory-test/test/datatype_test/enum_serializer_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

library;

import 'package:checks/checks.dart';
import 'package:fory/src/collection/stack.dart';
import 'package:fory/src/config/fory_config.dart';
import 'package:fory/src/deserialization_dispatcher.dart';
import 'package:fory/src/deserialization_context.dart';
import 'package:fory/src/fory_exception.dart';
import 'package:fory/src/memory/byte_reader.dart';
import 'package:fory/src/memory/byte_writer.dart';
import 'package:fory/src/meta/spec_wraps/type_spec_wrap.dart';
import 'package:fory/src/resolver/deserialization_ref_resolver.dart';
import 'package:fory/src/resolver/meta_string_writing_resolver.dart';
import 'package:fory/src/resolver/serialization_ref_resolver.dart';
import 'package:fory/src/resolver/struct_hash_resolver.dart';
import 'package:fory/src/resolver/type_resolver.dart';
import 'package:fory/src/serialization_dispatcher.dart';
import 'package:fory/src/serialization_context.dart';
import 'package:fory/src/serializer/enum_serializer.dart';
import 'package:fory_test/entity/enum_id_foo.dart';
import 'package:test/test.dart';

String _unusedTagLookup(Type _) => '';

final ForyConfig _config = ForyConfig();
final TypeResolver _typeResolver = TypeResolver.newOne(_config);

SerializationContext _newSerializationContext() {
return SerializationContext(
StructHashResolver.inst,
_unusedTagLookup,
SerializationDispatcher.I,
_typeResolver,
SerializationRefResolver.getOne(false),
SerializationRefResolver.noRefResolver,
MetaStringWritingResolver.newInst,
Stack<TypeSpecWrap>(),
);
}

DeserializationContext _newDeserializationContext() {
return DeserializationContext(
StructHashResolver.inst,
_unusedTagLookup,
_config,
(isXLang: true, oobEnabled: false),
DeserializationDispatcher.I,
DeserializationRefResolver.getOne(false),
_typeResolver,
Stack<TypeSpecWrap>(),
);
}

void main() {
group('Enum serializer', () {
test('writes and reads annotated enum ids when all values are annotated',
() {
final EnumSerializer serializer = EnumSerializer(false, [
EnumWithIds.A,
EnumWithIds.B,
EnumWithIds.C,
], {
10: EnumWithIds.A,
20: EnumWithIds.B,
30: EnumWithIds.C,
});

final ByteWriter writer = ByteWriter();
serializer.write(
writer,
EnumWithIds.B,
_newSerializationContext(),
);
final ByteReader encodedIdReader =
ByteReader.forBytes(writer.takeBytes());
check(encodedIdReader.readVarUint32Small7()).equals(20);

final ByteWriter idWriter = ByteWriter();
idWriter.writeVarUint32Small7(30);
final Enum value = serializer.read(
ByteReader.forBytes(idWriter.takeBytes()),
0,
_newDeserializationContext(),
);
check(value).equals(EnumWithIds.C);
});

test('falls back to ordinal serialization when id mapping is absent', () {
final EnumSerializer serializer = EnumSerializer(false, [
EnumPartialIds.A,
EnumPartialIds.B,
EnumPartialIds.C,
]);

final ByteWriter writer = ByteWriter();
serializer.write(
writer,
EnumPartialIds.B,
_newSerializationContext(),
);
final ByteReader encodedIdReader =
ByteReader.forBytes(writer.takeBytes());
check(encodedIdReader.readVarUint32Small7()).equals(1);
});

test('throws on unknown annotated enum id', () {
final EnumSerializer serializer = EnumSerializer(false, [
EnumWithIds.A,
EnumWithIds.B,
EnumWithIds.C,
], {
10: EnumWithIds.A,
20: EnumWithIds.B,
30: EnumWithIds.C,
});

final ByteWriter writer = ByteWriter();
writer.writeVarUint32Small7(99);

check(
() => serializer.read(
ByteReader.forBytes(writer.takeBytes()),
0,
_newDeserializationContext(),
),
).throws<DeserializationRangeException>();
});
});
}
22 changes: 22 additions & 0 deletions dart/packages/fory/lib/src/annotation/fory_enum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import 'fory_object.dart';
/// // enums
/// }
/// ```
@Target({TargetKind.enumType})
class ForyEnum extends ForyObject {
static const String name = 'ForyEnum';
static const List<TargetKind> targets = [TargetKind.enumType];
Expand All @@ -41,3 +42,24 @@ class ForyEnum extends ForyObject {

/// A constant instance of [ForyEnum].
const ForyEnum foryEnum = ForyEnum();

/// A class representing an enumeration id in the Fory framework.
///
/// This class extends [ForyObject] and is used to annotate enum ids
/// within the Fory framework.
/// Example:
/// ```
/// @foryEnum
/// enum Color {
/// @ForyEnumId(5)
/// blue,
/// @ForyEnumId(10)
/// white,
// }
/// ```
@Target({TargetKind.enumValue})
class ForyEnumId extends ForyObject {
final int id;

const ForyEnumId(this.id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class AnalysisTypeIdentifier {
null,
null,
null,
null
null,
null,
];
static final List<TypeStringKey> _keys = [
TypeStringKey(
Expand All @@ -66,6 +67,11 @@ class AnalysisTypeIdentifier {
'package',
'fory/src/annotation/fory_enum.dart',
),
TypeStringKey(
'ForyEnumId',
'package',
'fory/src/annotation/fory_enum.dart',
),
TypeStringKey(
'Uint8Type',
'package',
Expand Down Expand Up @@ -121,6 +127,10 @@ class AnalysisTypeIdentifier {
return _check(element, 3);
}

static bool isForyEnumId(ClassElement element) {
return _check(element, 4);
}

static void cacheForyEnumAnnotationId(int id) {
_ids[3] = id;
}
Expand All @@ -130,18 +140,18 @@ class AnalysisTypeIdentifier {
}

static bool isUint8Type(ClassElement element) {
return _check(element, 4);
return _check(element, 5);
}

static bool isUint16Type(ClassElement element) {
return _check(element, 5);
return _check(element, 6);
}

static bool isUint32Type(ClassElement element) {
return _check(element, 6);
return _check(element, 7);
}

static bool isUint64Type(ClassElement element) {
return _check(element, 7);
return _check(element, 8);
}
}
Loading
Loading