Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/schultek/dart_mappable
Improved json serialization and data classes with full support for generics, inheritance, customization and more.
https://github.com/schultek/dart_mappable
dart hacktoberfest
Last synced: 12 days ago
JSON representation
Improved json serialization and data classes with full support for generics, inheritance, customization and more.
- Host: GitHub
- URL: https://github.com/schultek/dart_mappable
- Owner: schultek
- License: mit
- Created: 2021-04-11T17:13:13.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-10-20T16:46:10.000Z (21 days ago)
- Last Synced: 2024-10-22T02:36:37.595Z (19 days ago)
- Topics: dart, hacktoberfest
- Language: Dart
- Homepage: https://pub.dev/packages/dart_mappable
- Size: 1.87 MB
- Stars: 156
- Watchers: 7
- Forks: 23
- Open Issues: 34
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
dart_mappable
Quickstart •
Documentation •
Example •
Package Comparison
Improved json serialization and data classes with
full support for generics, inheritance, customization and more.---
`dart_mappable` covers all basic features *(from/to json, == override, hashCode, toString(), copyWith)*
while adding new or improved support for advances use-cases including **generics, inheritance and
polymorphism, customization** and more.- 🎁 **Everything included**: Serialization, Equality, ToString, CopyWith and more.
- 🚀 **Excels at complexity**: It handles generics, polymorphism and multi-inheritance with ease.
- 🎛️ **Highly flexible**: Customize the serialization, add custom types or integrate with other packages.
- 🔥 **No compromises**: Its promise is that it just works, no matter what classes you throw at it.
*(If you find an unsupported case, you get a cookie 🍪. And please add an issue on [github](https://github.com/schultek/dart_mappable).)*## Quick Start
First, add `dart_mappable` as a dependency, together with `dart_mappable_builder` and `build_runner` as a dev_dependency.
```shell script
flutter pub add dart_mappable
flutter pub add build_runner --dev
flutter pub add dart_mappable_builder --dev
```---
Next annotate your classes that you want to use with `@MappableClass()` and add the
appropriate `part` directive to include the generated `.mapper.dart` file:```dart
// This file is "model.dart"
import 'package:dart_mappable/dart_mappable.dart';// Will be generated by dart_mappable
part 'model.mapper.dart';@MappableClass()
class MyClass with MyClassMappable {
final int myValue;MyClass(this.myValue);
}
```To use a class you must:
- annotate the class with `@MappableClass()` and
- apply a mixin with the name of the class plus `Mappable`.***Tip**: Don't worry if the mixin don't exist at first, just run code-generation once an it will be created.
The builder will also warn you if you define your class without the proper mixin.****Note**: For generic classes (e.g. `MyClass`) make sure to also provide all type parameters
to the mixin (`... with MyClassMappable`).*---
In order to generate the serialization code, run the following command:
```shell script
dart pub run build_runner build
```***Tip**: You'll need to re-run code generation each time you are making changes to your annotated classes.
During development, you can use `watch` to automatically watch your changes: `dart pub run build_runner watch`.*This will generate a `.mapper.dart` file for each of your files containing annotated classes.
---
Last step is to use the generated mappers. There are two main ways to interact with your models
using this package:1. Through the generated `Mapper` classes, and
2. through the methods defined by the generated mixin.```dart
...void main() {
// Decode a [Map] using the [MyClassMapper] class:
MyClass myClass = MyClassMapper.fromMap({'myValue': 123});
// Or decode directly from json:
MyClass myClass2 = MyClassMapper.fromJson('{"myValue": 123}');
// Encode an instance of your class using the methods provided by the mixin:
Map map = myClass.toMap();
String json = myClass.toJson();
// There are also implementations generated for [operator ==], [hashCode] and [toString]:
bool thisIsTrue = (myClass == myClass2);
print(myClass);
// Last you can use [copyWith] to create a copy of an object:
MyClass myClass3 = myClass.copyWith(myValue: 0);
}
```***Beware**: The `.toJson()` method returns a `String`. If you are migrating from `json_serializable`, you might
be used to this returning a `Map` instead. Make sure to properly adapt your code to this change,
as not doing so might lead to unexpected behavior. Find more about the recommended migration path
[here](https://pub.dev/documentation/dart_mappable/latest/topics/Migration%20and%20Compatibility-topic.html)*.## Overview
To setup, annotate your model classes with `@MappableClass()` and your enums with `@MappableEnum()`.
Each annotation has a set of properties to configure the generated code.```dart
@MappableClass()
class MyClass with MyClassMappable { ... }@MappableEnum()
enum MyEnum { ... }
```***Tip**: Check out the documentation about
[Models](https://pub.dev/documentation/dart_mappable/latest/topics/Models-topic.html) and
[Enums](https://pub.dev/documentation/dart_mappable/latest/topics/Enums-topic.html).*For deserialization, `dart_mappable` will use the first available constructor of a class, but you
can use a specific constructor using the `@MappableConstructor()` annotation.```dart
@MappableClass()
class MyClass with MyClassMappable {
MyClass(); // Don't use this@MappableConstructor()
MyClass.special(); // Use this
}
```You can also annotate a single field or constructor parameter of a class using `@MappableField()`
to set a specific json key or add custom hooks.```dart
@MappableClass()
class MyClass with MyClassMappable {
MyClass(this.value);@MappableField(key: 'my_key')
String value;
}
```***Note**: This can only be used on a field if it is directly assigned as a constructor parameter (`MyClass(this.myField)`).
Setting this annotation on any other field will have no effect.
(Read [Utilizing Constructors](https://pub.dev/documentation/dart_mappable/latest/topics/Models-topic.html#utilizing-constructors) for an explanation why this is.)****Tip**: Hooks are a way to customize the serialization of any field or class.
Read more in the documentation about [Mapping Hooks](https://pub.dev/documentation/dart_mappable/latest/topics/Mapping%20Hooks-topic.html).*You can add the `@MappableLib()` annotation to your `library` statement to set a default configuration
for all included classes and enums, e.g. the case style for json keys.```dart
@MappableLib(caseStyle: CaseStyle.camelCase) // will be applied to all classes
library model;part 'model.mapper.dart';
@MappableClass() // no need to set caseStyle here
class MyClass with MyClassMappable {
...
}
```***Tip**: Check out the documentation to see all available [Configuration](https://pub.dev/documentation/dart_mappable/latest/topics/Configuration-topic.html) options.*
---
Here are again all **six** annotations that you can use in your code:
1. `@MappableClass()` can be used on a class to specify options like the `caseStyle` of the json keys, whether to ignore null values, or [hooks](https://pub.dev/documentation/dart_mappable/latest/topics/Mapping%20Hooks-topic.html).
2. `@MappableConstructor()` can be used on a constructor to mark this to be used for decoding. It has no properties.
3. `@MappableField()` can be used on a constructor parameter or a field to specify a json key to be used instead of the field name, or [hooks](https://pub.dev/documentation/dart_mappable/latest/topics/Mapping%20Hooks-topic.html).
4. `@MappableEnum()` can be used on an enum to specify the `mode` or `caseStyle` of the encoded enum values, or the `defaultValue`.
5. `@MappableValue()` can be used on an enum value to specify a custom encoded value to use.
6. `@MappableLib()` can be used on a library statement or import / export statement to set a default configuration for the annotated library or include / exclude classes.### Mapper Interface
`dart_mappable` will generate `Mapper` classes that provide these methods or properties:
- `Mapper.fromMap(Map map)` will take an encoded map object and return a decoded object of type `ClassName`.
- `Mapper.fromJson(String json)` internally uses `fromMap` but works with json encoded `String`s.***Tip**: If you prefer to use `MyClass.fromJson` over `MyClassMapper.fromJson`, add the `fromJson` and
`fromMap` methods directly to your class like this:*```
class MyClass with MyClassMappable {
...static final fromMap = MyClassMapper.fromMap;
static final fromJson = MyClassMapper.fromJson;
}
```The generated `Mappable` mixin will come with the following methods:
- `toMap()` and `toJson()`.
- `copyWith()` to create copies of your class instance (see [Copy With](https://pub.dev/documentation/dart_mappable/latest/topics/Copy-With-topic.html)).
- overrides for `operator ==`, `hashCode` and `toString()`.## Full Documentation
See the full documentation [here](https://pub.dev/documentation/dart_mappable/latest/topics/Introduction-topic.html)
or jump directly to the topic you are looking for:- [**Models**](https://pub.dev/documentation/dart_mappable/latest/topics/Models-topic.html)
show you how to structure and annotate your data models.
- [**Enums**](https://pub.dev/documentation/dart_mappable/latest/topics/Enums-topic.html)
show you how to structure and annotate your enums.
- [**Records**](https://pub.dev/documentation/dart_mappable/latest/topics/Records-topic.html)
show you how to use records as part of your models.
- [**Configuration**](https://pub.dev/documentation/dart_mappable/latest/topics/Configuration-topic.html)
goes into the different configuration options you have.
- [**Copy-With**](https://pub.dev/documentation/dart_mappable/latest/topics/Copy-With-topic.html)
describes the copy-with functionalities and how to use them.
- [**Polymorphism**](https://pub.dev/documentation/dart_mappable/latest/topics/Polymorphism-topic.html)
shows how to do polymorphic classes and inheritance.
- [**Generics**](https://pub.dev/documentation/dart_mappable/latest/topics/Generics-topic.html)
explain generic decoding and how to use it.
- [**Mapping Hooks**](https://pub.dev/documentation/dart_mappable/latest/topics/Mapping%20Hooks-topic.html)
shows how to use hooks to customize your de- and encoding process.
- [**Custom Mappers**](https://pub.dev/documentation/dart_mappable/latest/topics/Custom%20Mappers-topic.html)
explains how to set up and use (non-generated) custom mappers.
- [**Mapper Container**](https://pub.dev/documentation/dart_mappable/latest/topics/Mapper%20Container-topic.html)
describes the inner workings of mapper containers in more detail.
- [**Migration and Compatibility**](https://pub.dev/documentation/dart_mappable/latest/topics/Migration%20and%20Compatibility-topic.html)
shows you how you can incrementally migrate from other packages like freezed or json_serializable and use compatible
packages like fast_immutable_collections.