toon_serializable
The official code generator for Token-Oriented Object Notation (TOON) models in Dart. Automatically generates TOON serialization code using build_runner.
Features
- 🚀 Automatic Code Generation: Generate
toToon()andfromToon()methods with a single annotation - 🔄 Field Renaming: Support for multiple field renaming strategies (snake_case, kebab-case, PascalCase, camelCase)
- 🎯 Custom Keys: Override field names with
@ToonKeyannotation - 📦 Type Safety: Full support for nullable types and generic lists
- ⚡ Zero Runtime Overhead: All serialization logic is generated at compile time
- 🔧 Easy Integration: Works seamlessly with
build_runnerand existing Dart projects
Installation
Add the following to your pubspec.yaml:
dependencies:
toon_annotation: ^1.0.0
toon_dart: ^1.0.0
dev_dependencies:
toon_serializable: ^1.0.1
build_runner: ^2.10.3
Then run:
dart pub get
Configuration
The package is automatically configured via build.yaml. No manual configuration is required for most use cases.
Usage
Basic Example
- Define your model class with the
@ToonSerializableannotation:
import 'package:toon_annotation/toon_annotation.dart';
import 'package:toon_dart/toon_dart.dart';
part 'user_model.toon_serializable.g.part'; // Generated file
@ToonSerializable()
class User {
final String name;
final int age;
User({required this.name, required this.age});
// These methods will be generated
factory User.fromToon(String toon) => _$UserFromToon(toon);
String toToon() => _$UserToToon(this);
}
- Run the code generator:
dart run build_runner build
- Use the generated code:
final user = User(name: 'Alice', age: 30);
final toonString = user.toToon(); // Serialize to TOON
final decodedUser = User.fromToon(toonString); // Deserialize from TOON
Field Renaming
Use fieldRename to automatically convert field names:
@ToonSerializable(fieldRename: FieldRename.snake)
class User {
final String firstName; // Serializes as 'first_name'
final int userAge; // Serializes as 'user_age'
User({required this.firstName, required this.userAge});
factory User.fromToon(String toon) => _$UserFromToon(toon);
String toToon() => _$UserToToon(this);
}
Custom Field Keys
Override specific field names with @ToonKey:
@ToonSerializable(fieldRename: FieldRename.snake)
class User {
final String firstName; // Serializes as 'first_name'
@ToonKey(name: 'user_age')
final int age; // Serializes as 'user_age' (not 'age')
User({required this.firstName, required this.age});
factory User.fromToon(String toon) => _$UserFromToon(toon);
String toToon() => _$UserToToon(this);
}
Advanced Options
@ToonSerializable(
fieldRename: FieldRename.snake,
useTabularArrays: false, // Set to true for tabular array format
strictKeys: true, // Enable strict key validation
)
class User {
// ... your fields
}
Running the Generator
One-time Generation
dart run build_runner build
Watch Mode (Auto-regenerate on file changes)
dart run build_runner watch
Clean Build (Delete conflicting outputs)
dart run build_runner build --delete-conflicting-outputs
Important Notes
⚠️ Known Issue: Part Declaration
The generated .part file requires manual addition of the part of declaration.
After running build_runner, you must manually add the following line at the top of each generated .part file:
part of 'your_file_name.dart';
For example, if your file is user_model.dart and the generated file is user_model.toon_serializable.g.part, add:
part of 'user_model.dart';
// ... rest of generated code
Why is this needed? The SharedPartBuilder from source_gen should automatically add this declaration, but due to current limitations, it must be added manually. This is a known issue that will be addressed in a future release.
Workaround: You can create a simple script or use your IDE's find-and-replace to add this line after each code generation.
Field Renaming Strategies
| Strategy | Example Input | Example Output |
|---|---|---|
FieldRename.snake |
firstName |
first_name |
FieldRename.kebab |
firstName |
first-name |
FieldRename.pascal |
firstName |
FirstName |
FieldRename.camel |
FirstName |
firstName |
| None (default) | firstName |
firstName |
Supported Types
- Primitives:
String,int,double,bool - Nullable types:
String?,int?, etc. - Lists:
List<String>,List<int>, etc. - Nested objects: Any class annotated with
@ToonSerializable - Maps:
Map<String, dynamic>(viatoon_dart)
Examples
See the /example directory for complete working examples.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Issues
If you encounter any issues or have feature requests, please file them on the issue tracker.
License
This package is licensed under the MIT License. See the LICENSE file for details.
Related Packages
- toon_annotation - Annotation definitions
- toon_dart - Low-level TOON parser
Libraries
- builder
- toon_serializable
- Support for doing something awesome.