1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224# 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
```dart
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:
```bash
dart run build_runner build
```
This generates the necessary code in `example.g.dart` and creates the `_$SomeClassFory` mixin.
### Serializing and Deserializing
```dart
Fory fory = Fory(
refTracking: true,
);
fory.register($SomeClass, "example.SomeClass");
SomeClass obj = SomeClass(1, 'SomeClass', {'a': 1.0});
// Serialize
Uint8List bytes = fory.toFory(obj);
// Deserialize
obj = fory.fromFory(bytes) as SomeClass;
```
### Enum Serialization
```dart
import 'package:fory/fory.dart';
part 'example.g.dart';
@foryEnum
enum EnumFoo {
A,
B
}
```
Registration is similar to classes:
```dart
fory.register($EnumFoo, "example.EnumFoo");
```
## Type Support
Apache Fory™ Dart currently supports the following type mappings in XLANG mode:
| Fory Type | Dart Type |
| ------------- | ------------------------------------------ |
| bool | bool |
| int8 | fory.Int8 |
| int16 | fory.Int16 |
| int32 | fory.Int32 |
| var_int32 | fory.Int32 |
| int64 | int |
| var_int64 | int |
| sli_int64 | int |
| float32 | fory.Float32 |
| float64 | double |
| string | String |
| enum | Enum |
| named_enum | Enum |
| named_struct | class |
| list | List |
| set | Set (LinkedHashSet, HashSet, SplayTreeSet) |
| map | Map (LinkedHashMap, HashMap, SplayTreeMap) |
| timestamp | fory.TimeStamp |
| local_date | fory.LocalDate |
| binary | Uint8List |
| bool_array | BoolList |
| int8_array | Int8List |
| int16_array | Int16List |
| int32_array | Int32List |
| int64_array | Int64List |
| float32_array | Float32List |
| float64_array | Float64List |
## 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](https://pub.dev/packages/test) framework.
To run tests:
```bash
# 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:
```bash
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
```