tree: 677b22a3a518641d338e678b59bb521594172376
  1. example/
  2. note/
  3. packages/
  4. .gitignore
  5. analysis_options.yaml
  6. build.yaml
  7. CHANGELOG.md
  8. pubspec.lock
  9. pubspec.yaml
  10. README.md
dart/README.md

Apache Fory™ Dart

Overview

This PR adds Dart language support to Apache Fory™, implementing a comprehensive serialization solution for Dart and Flutter applications. Apache Fory™ Dart consists of approximately 15,000 lines of code and provides an efficient serialization mechanism that works within Flutter's reflection limitations.

Implementation Approach

Dart supports reflection, but Flutter explicitly prohibits it. To address this constraint, Apache Fory™ Dart uses a combination of:

  1. Core serialization/deserialization logic
  2. Static code generation for type handling

This approach ensures compatibility with Flutter while maintaining the performance and flexibility expected from Apache Fory™.

Features

  • XLANG mode support for cross-language serialization
  • Reference tracking for handling object graphs
  • Support for primitive types, collections, and custom classes
  • Serializer registration system
  • Code generation for class and enum serialization
  • Support for nested collections with automatic generic type conversion
  • Custom serializer registration
  • Support for using ByteWriter/ByteReader as serialization sources

Usage Examples

Basic Class Serialization

import 'package:fory/fory.dart';

part 'example.g.dart';

@foryClass
class SomeClass with _$SomeClassFory {
  late int id;
  late String name;
  late Map<String, double> map;

  SomeClass(this.id, this.name, this.map);

  SomeClass.noArgs();
}

After annotating your class with @foryClass, run:

dart run build_runner build

This generates the necessary code in example.g.dart and creates the _$SomeClassFory mixin.

Serializing and Deserializing

Fory fory = Fory(ref: true);
fory.register($SomeClass, typename: "example.SomeClass");
SomeClass obj = SomeClass(1, 'SomeClass', {'a': 1.0});

// Serialize
Uint8List bytes = fory.serialize(obj);

// Deserialize
obj = fory.deserialize(bytes) as SomeClass;

Enum Serialization

import 'package:fory/fory.dart';

part 'example.g.dart';

@foryEnum
enum EnumFoo {
  A,
  B
}

Registration is similar to classes:

fory.register($EnumFoo, typename: "example.EnumFoo");

Type Support

Apache Fory™ Dart currently supports the following type mappings in XLANG mode:

Fory TypeDart Type
boolbool
int8fory.Int8
int16fory.Int16
int32fory.Int32
var_int32fory.Int32
int64int
var_int64int
sli_int64int
float32fory.Float32
float64double
stringString
enumEnum
named_enumEnum
named_structclass
listList
setSet (LinkedHashSet, HashSet, SplayTreeSet)
mapMap (LinkedHashMap, HashMap, SplayTreeMap)
timestampfory.TimeStamp
local_datefory.LocalDate
binaryUint8List
bool_arrayBoolList
int8_arrayInt8List
int16_arrayInt16List
int32_arrayInt32List
int64_arrayInt64List
float32_arrayFloat32List
float64_arrayFloat64List

Project Structure

The implementation is organized into three main components:

  1. Codegen: Located at dart/packages/fory/lib/src/codegen Handles static code generation for serialization/deserialization.

  2. ForyCore: Located at dart/packages/fory/lib/src Contains the core serialization and deserialization logic.

  3. ForyTest: Located at dart/fory-test Comprehensive test suite for Apache Fory™ Dart functionality.

Testing Approach

The test suite is inspired by Apache Fory™ Java's testing approach and includes:

  • Data Type Tests: Validates custom data types implemented for Dart
  • Code Generation Tests: Ensures correctness of the generated static code
  • Buffer Tests: Validates correct memory handling for primitive types
  • Cross-Language Tests: Tests functionality against other Apache Fory™ implementations
  • Performance Tests: Simple benchmarks for serialization/deserialization performance

Running Tests

Tests use the standard dart test framework.

To run tests:

# First, generate necessary code
cd fory-test
dart run build_runner build

# Run all tests
dart test

# For more options (skipping tests, platform-specific tests, etc.)
# See: https://github.com/dart-lang/test/blob/master/pkgs/test/README.md

Additional Configuration

Inside the fory-test/test_config directory you will find YAML configuration files required by certain tests (for example, the cross_language tests). Before executing those tests, please review and adjust the configs in fory-test/test_config (or provide your own) so that they match your environment.

Code Quality

Apache Fory™ Dart maintains high code quality standards. You can verify this using:

dart analyze
dart fix --dry-run
dart fix --apply

Current Limitations

  • Only supports XLANG mode (priority was given to cross-language compatibility)
  • No out-of-band buffer functionality
  • No data type compression (e.g., String compression)
  • Generic parameters in user-defined types can be serialized but require manual type conversion after deserialization

Development Information

  • Dart SDK: 3.6.1

Dependencies

fory package:

analyzer: '>=6.5.0 <8.0.0'
build: ^2.4.1
build_config: ^1.1.0
collection: ^1.19.1
meta: ^1.14.0
source_gen: ^2.0.0
glob: ^2.1.3
decimal: ^3.2.1
lints: ^5.0.0
build_runner: ^2.4.6

fory-test package:

path: ^1.9.1
yaml: ^3.1.3
lints: ^5.0.0
build: ^2.4.2
build_runner: ^2.4.15
test: ^1.24.0
checks: ^0.3.0
build_test: ^2.2.3
analyzer: '>=6.5.0 <8.0.0'
collection: ^1.19.1