Skip to content

Commit 90a45dd

Browse files
authored
docs(dart): add dart docs (#3560)
## Why? ## What does this PR do? add dart docs ## Related issues ## AI Contribution Checklist - [ ] Substantial AI assistance was used in this PR: `yes` / `no` - [ ] If `yes`, I included a completed [AI Contribution Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs) in this PR description and the required `AI Usage Disclosure`. - [ ] If `yes`, my PR description includes the required `ai_review` summary and screenshot evidence of the final clean AI review results from both fresh reviewers on the current PR diff or current HEAD after the latest code changes. ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
1 parent 39700ab commit 90a45dd

20 files changed

Lines changed: 1666 additions & 128 deletions

dart/README.md

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -143,79 +143,3 @@ The test suite is inspired by Apache Fory™ Java's testing approach and include
143143
- **Buffer Tests**: Validates correct memory handling for primitive types
144144
- **Cross-Language Tests**: Tests functionality against other Apache Fory™ implementations
145145
- **Performance Tests**: Simple benchmarks for serialization/deserialization performance
146-
147-
### Running Tests
148-
149-
Tests use the standard [dart test](https://pub.dev/packages/test) framework.
150-
151-
To run tests:
152-
153-
```bash
154-
# First, generate necessary code
155-
cd fory-test
156-
dart run build_runner build
157-
158-
# Run all tests
159-
dart test
160-
161-
# For more options (skipping tests, platform-specific tests, etc.)
162-
# See: https://github.com/dart-lang/test/blob/master/pkgs/test/README.md
163-
```
164-
165-
#### Additional Configuration
166-
167-
Inside the `fory-test/test_config` directory you will find YAML configuration files required by certain tests (for example, the `cross_language` tests).
168-
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.
169-
170-
## Code Quality
171-
172-
Apache Fory™ Dart maintains high code quality standards. You can verify this using:
173-
174-
```bash
175-
dart analyze
176-
dart fix --dry-run
177-
dart fix --apply
178-
```
179-
180-
## Current Limitations
181-
182-
- Only supports XLANG mode (priority was given to cross-language compatibility)
183-
- No out-of-band buffer functionality
184-
- No data type compression (e.g., String compression)
185-
- Generic parameters in user-defined types can be serialized but require manual type conversion after deserialization
186-
187-
## Development Information
188-
189-
- **Dart SDK**: 3.6.1
190-
191-
## Dependencies
192-
193-
### fory package:
194-
195-
```
196-
analyzer: '>=6.5.0 <8.0.0'
197-
build: ^2.4.1
198-
build_config: ^1.1.0
199-
collection: ^1.19.1
200-
meta: ^1.14.0
201-
source_gen: ^2.0.0
202-
glob: ^2.1.3
203-
decimal: ^3.2.1
204-
lints: ^5.0.0
205-
build_runner: ^2.4.6
206-
```
207-
208-
### fory-test package:
209-
210-
```
211-
path: ^1.9.1
212-
yaml: ^3.1.3
213-
lints: ^5.0.0
214-
build: ^2.4.2
215-
build_runner: ^2.4.15
216-
test: ^1.24.0
217-
checks: ^0.3.0
218-
build_test: ^2.2.3
219-
analyzer: '>=6.5.0 <8.0.0'
220-
collection: ^1.19.1
221-
```

dart/packages/fory-test/test/compatible_struct_slots_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:test/test.dart';
44

55
void main() {
66
test('compatible named struct round trip scopes nested struct slots', () {
7-
final fory = Fory(config: const Config(compatible: true));
7+
final fory = Fory(compatible: true);
88
registerXlangType(
99
fory,
1010
Color,

dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,8 @@ void _writeFile(Uint8List bytes) {
4141

4242
Fory _newFory({bool compatible = false}) {
4343
return Fory(
44-
config: Config(
45-
compatible: compatible,
46-
checkStructVersion: !compatible,
47-
),
44+
compatible: compatible,
45+
checkStructVersion: !compatible,
4846
);
4947
}
5048

dart/packages/fory-test/test/generated_round_trip_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void main() {
8484

8585
test('fixed payload stays smaller than evolving payload in compatible mode',
8686
() {
87-
final fory = Fory(config: const Config(compatible: true));
87+
final fory = Fory(compatible: true);
8888
PersonFory.register(
8989
fory,
9090
EvolvingPayload,

dart/packages/fory/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
## 0.17.0-dev
22

3-
- Rewrite the Dart runtime around `Fory`, `Buffer`, `WriteContext`, `ReadContext`, and `TypeResolver`.
3+
- Dart runtime implementation around `Fory`, `Buffer`, `WriteContext`, `ReadContext`, and `TypeResolver`.

dart/packages/fory/README.md

Lines changed: 218 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,234 @@
11
# Apache Fory Dart
22

3-
This package provides the Dart runtime for Apache Fory xlang serialization.
3+
Apache Fory Dart is the Dart xlang runtime for Apache Fory. It reads and writes
4+
Fory's cross-language wire format and is designed around generated serializers
5+
for annotated Dart models, with customized serializers available for advanced use
6+
cases.
47

5-
For normal application code, use annotated objects plus the generated
6-
library-level namespace such as `ExampleFory.register(fory, Person, id: 1)` or
7-
`ExampleFory.register(fory, Person, namespace: 'example', typeName: 'Person')`.
8-
Those generated helpers keep serializer metadata private to the source library
9-
and register directly through generated serializer metadata, while manual
10-
`Serializer` implementations
11-
remain the advanced escape hatch for external types, custom wire behavior, or
12-
manual union implementations through `Fory.registerSerializer(...)`.
8+
## Features
139

14-
The runtime is built around a small public surface:
10+
- Cross-language serialization with the Fory xlang format
11+
- Generated serializers for annotated structs and enums
12+
- Compatible mode for schema evolution
13+
- Optional reference tracking for shared and circular object graphs
14+
- Manual serializers for external types, custom payloads, and unions
15+
- Explicit xlang value wrappers such as `Int32`, `UInt32`, `Float16`,
16+
`Float32`, `LocalDate`, and `Timestamp`
17+
18+
## Getting Started
19+
20+
Add `fory` to your package dependencies.
21+
22+
```yaml
23+
dependencies:
24+
fory: ^0.17.0-dev
25+
26+
dev_dependencies:
27+
build_runner: ^2.4.13
28+
```
29+
30+
## Basic Usage
31+
32+
Use `@ForyStruct()` for generated struct serializers and include the generated
33+
part file.
34+
35+
```dart
36+
import 'package:fory/fory.dart';
37+
38+
part 'person.fory.dart';
39+
40+
enum Color {
41+
red,
42+
blue,
43+
}
44+
45+
@ForyStruct()
46+
class Person {
47+
Person();
48+
49+
String name = '';
50+
Int32 age = Int32(0);
51+
Color favoriteColor = Color.red;
52+
List<String> tags = <String>[];
53+
}
54+
55+
void main() {
56+
final fory = Fory();
57+
58+
PersonFory.register(
59+
fory,
60+
Color,
61+
namespace: 'example',
62+
typeName: 'Color',
63+
);
64+
PersonFory.register(
65+
fory,
66+
Person,
67+
namespace: 'example',
68+
typeName: 'Person',
69+
);
70+
71+
final person = Person()
72+
..name = 'Ada'
73+
..age = Int32(36)
74+
..favoriteColor = Color.blue
75+
..tags = <String>['engineer', 'mathematician'];
76+
77+
final bytes = fory.serialize(person);
78+
final roundTrip = fory.deserialize<Person>(bytes);
79+
80+
print(roundTrip.name);
81+
}
82+
```
83+
84+
Generate the companion file before running the program:
85+
86+
```bash
87+
dart run build_runner build --delete-conflicting-outputs
88+
```
89+
90+
## Type Registration
91+
92+
Generated types register through the generated library namespace.
93+
94+
```dart
95+
PersonFory.register(fory, Person, id: 100);
96+
```
97+
98+
Or use namespace and type name registration:
99+
100+
```dart
101+
PersonFory.register(
102+
fory,
103+
Person,
104+
namespace: 'example',
105+
typeName: 'Person',
106+
);
107+
```
108+
109+
Exactly one registration mode is required:
110+
111+
- `id: ...`
112+
- `namespace: ...` and `typeName: ...`
113+
114+
Keep the same registration identity on all runtimes that exchange the type.
115+
116+
## Configuration
117+
118+
Configure the runtime through `Config`.
119+
120+
```dart
121+
final fory = Fory(
122+
compatible: true,
123+
maxDepth: 256,
124+
maxCollectionSize: 1 << 20,
125+
maxBinarySize: 64 * 1024 * 1024,
126+
);
127+
```
128+
129+
Key options:
130+
131+
- `compatible`: enables compatible struct encoding and decoding
132+
- `checkStructVersion`: enables struct-version validation in
133+
schema-consistent mode
134+
- `maxDepth`: limits nesting depth for one operation
135+
- `maxCollectionSize`: limits collection and map payload sizes
136+
- `maxBinarySize`: limits binary payload size
137+
138+
## Reference Tracking
139+
140+
Enable root-level reference tracking only when the root value itself is a graph
141+
or container that needs shared-reference tracking.
142+
143+
```dart
144+
final shared = String.fromCharCodes('shared'.codeUnits);
145+
final bytes = fory.serialize(<Object?>[shared, shared], trackRef: true);
146+
final roundTrip = fory.deserialize<List<Object?>>(bytes);
147+
```
148+
149+
For generated structs, prefer field-level reference metadata:
150+
151+
```dart
152+
@ForyStruct()
153+
class NodeList {
154+
NodeList();
155+
156+
@ForyField(ref: true)
157+
List<Object?> values = <Object?>[];
158+
}
159+
```
160+
161+
## Customized Serializers
162+
163+
Use `Serializer<T>` when a type cannot use generated struct support or when you
164+
need custom wire behavior.
165+
166+
```dart
167+
import 'package:fory/fory.dart';
168+
169+
final class Person {
170+
Person(this.name, this.age);
171+
172+
final String name;
173+
final int age;
174+
}
175+
176+
final class PersonSerializer extends Serializer<Person> {
177+
const PersonSerializer();
178+
179+
@override
180+
void write(WriteContext context, Person value) {
181+
final buffer = context.buffer;
182+
buffer.writeUtf8(value.name);
183+
buffer.writeInt64(value.age);
184+
}
185+
186+
@override
187+
Person read(ReadContext context) {
188+
final buffer = context.buffer;
189+
return Person(buffer.readUtf8(), buffer.readInt64());
190+
}
191+
}
192+
193+
void main() {
194+
final fory = Fory();
195+
fory.registerSerializer(
196+
Person,
197+
const PersonSerializer(),
198+
namespace: 'example',
199+
typeName: 'Person',
200+
);
201+
202+
final bytes = fory.serialize(Person('Ada', 36));
203+
final roundTrip = fory.deserialize<Person>(bytes);
204+
print(roundTrip.name);
205+
}
206+
```
207+
208+
## Public API
209+
210+
The main exported API includes:
15211

16212
- `Fory`
17213
- `Config`
18214
- `Buffer`
19215
- `WriteContext`
20216
- `ReadContext`
21217
- `Serializer`
218+
- `UnionSerializer`
22219
- `ForyStruct`
23220
- `ForyField`
221+
- Numeric and temporal wrappers such as `Int8`, `Int16`, `Int32`, `UInt8`,
222+
`UInt16`, `UInt32`, `Float16`, `Float32`, `LocalDate`, and `Timestamp`
24223

25-
Generated structs and enums register through the generated library namespace.
26-
Generated wrappers require an explicit registration mode: pass `id` for
27-
id-based registration, or pass both `namespace` and `typeName` for name-based
28-
registration.
29-
30-
## Public API
31-
32-
- `Fory`: root facade for xlang serialization, deserialization, generated type registration, and advanced manual serializer registration.
33-
- `Config`: immutable runtime options for compatible mode and safety limits.
34-
- `Buffer`: reusable byte buffer with explicit reader and writer indices.
35-
- `WriteContext` and `ReadContext`: advanced context APIs used by generated and manual serializers.
36-
- `Serializer`: low-level extension point for manual serializers and generated code.
37-
- `ForyStruct` and `ForyField`: annotations for struct code generation.
38-
- Numeric wrapper and time types such as `Int32`, `UInt32`, `Float16`, `LocalDate`, and `Timestamp`: xlang value types when Dart primitives are not precise enough to describe the wire type.
39-
40-
Refer to the Dart doc comments on each exported symbol for the precise contract of each type and method.
41-
42-
## Example
43-
44-
The primary example uses generated serializers:
45-
46-
1. Generate the example companion file:
47-
`dart run build_runner build --delete-conflicting-outputs`
48-
2. Run the example:
49-
`dart run example/example.dart`
224+
## Cross-Language Notes
50225

51-
The example library exposes `ExampleFory.register(...)` for generated
52-
registration, for example `ExampleFory.register(fory, Person, namespace:
53-
'example', typeName: 'Person')`.
226+
- The Dart runtime only supports xlang payloads.
227+
- Register user-defined types before serialization or deserialization.
228+
- Keep numeric IDs or `namespace + typeName` mappings consistent across
229+
languages.
230+
- Use wrappers or numeric field annotations when the exact xlang wire type
231+
matters.
54232

55-
The advanced manual serializer example lives at `example/manual_serializer.dart`.
233+
For the xlang wire format and type mapping details, see the Apache Fory
234+
specification in the main repository.

0 commit comments

Comments
 (0)