Hello. My name is Masaru Hirose.
The Flutter macro announcement at Google I/O 2024.
The Masamune framework continued to be developed with the ultimate goal of providing "macro support for all application development".
I have been relying on freezed and json_serializable to support macros. We have decided to perform data class and Json conversions within the Masamune framework.
I’ve put together some instructions on how to use it, so if you’re interested, go ahead and give it a try!
{content}
katana_value
Introduction
Dart's macro functionality enables the creation of immutable data classes.
Support for comparison operators
, implementation of copyWith
, and maintenance of toString
can be done simply by annotating the file.
It also enables conversion from Json
and conversion to Json
.
It can be easily defined as follows
@DataValue
class Person {
Person({
required String name,
int? age,
});
}
It can be used as follows
final person = Person(name: "Kanimiso");
final copied = person.copyWith(age: 20);
final json = person.toJson();
print(json); // {name: "Kanimiso", age: 20}
Preparation
- Change to Dart dev channel or Flutter master channel.
-
Run
dart --version
to update the version of Dart from3.5.0-152
. -
Set the version of DartSDK in
pubspec.yaml
to^3.5.0-152
. -
Add the following code to
analysis_options.yaml
.analyzer: enable-experiment: - macros
Installation
Import the following packages.
flutter pub add katana_value
Implementation
Create data class
Annotation of @DataValue
is added to the class you want to make into a data class.
Define the required field types and names in the constructor. This is all that is required to create the data class.
@DataValue
class Person {
Person({
required String name,
int? age,
});
}
Using data classes
The defined class can be objectified as is.
final person = Person(name: "Kanimiso", age: 20);
It is also possible to use methods such as copyWith
, toJson
, and fromJson
.
final json = {"name": "Kanimiso", "age": 20};
final person = Person.fromJson(json);
print(person.toString()); // Person(name: Kanimiso, age: 20)
final copied = person.copyWith(age: 30);
print(copied.toJson()); // {"name": "Kanimiso", "age": 30};
Types that can be converted to Json
Initially, the following types can be converted (including Nullable)
-
int
-
double
-
num
-
String
-
bool
-
Iterable
-
List
-
Set
-
Map
Support for new Json conversion types
The above types are initially available, but if you have a new type you wish to support for Json conversion, use DataValueJsonConverter
.
-
Create a class that extends
DataValueJsonConverter
.class ModelCounterJsonConverter extends DataValueJsonConverter { const ModelCounterJsonConverter(); @override Map<String, dynamic>? toJson(dynamic value) { if (value is ModelCounter) { return value.toJson(); } return null; } @override dynamic fromJson(String key, Map<String, dynamic> json) { final map = json[key]; if(map is Map<String, Object?> && map["#type"] == "ModelCounter") { return PersonBase.fromJson(map); } return null; } }
-
Register the created class with
DataValueJsonConverter.register
at application startup, such as in the main method.void main(){ DataValueJsonConverter.register(const ModelCounterJsonConverter()); }
Execution
The following command is used to execute it.
dart run --enable-experiment=macros bin/my_app.dart
Conclusion
I made it for my own use, but if you think it fits your implementation philosophy, by all means, use it!
Also, I releasing the source here, so issues and PullRequests are welcome!
If you have any further work requests, please contact me directly through my Twitter or website!
GitHub Sponsors
Sponsors are always welcome. Thank you for your support!