Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5439c41
commit 206743f
Showing
11 changed files
with
439 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Files and directories created by pub | ||
.dart_tool/ | ||
.packages | ||
|
||
# Omit commiting pubspec.lock for library packages: | ||
# https://dart.dev/guides/libraries/private-files#pubspeclock | ||
pubspec.lock | ||
|
||
# Conventional directory for build outputs | ||
build/ | ||
|
||
# Directory created by dartdoc | ||
doc/api/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "enough_serialization", | ||
"request": "launch", | ||
"type": "dart" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## 1.0.0 | ||
|
||
- Initial version |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
|
||
Serialize to and deserialize from JSON in runtime. | ||
This pure Dart library does not depend on build time generation. | ||
|
||
## Installation | ||
|
||
## Installation | ||
Add this dependency your pubspec.yaml file: | ||
|
||
``` | ||
dependencies: | ||
enough_serialization: ^1.0.0 | ||
``` | ||
The latest version or `enough_serialization` is [![enough_serialization version](https://img.shields.io/pub/v/enough_serialization.svg)](https://pub.dartlang.org/packages/enough_serialization). | ||
|
||
|
||
## Usage | ||
|
||
A simple usage example: | ||
|
||
```dart | ||
import 'package:enough_serialization/enough_serialization.dart'; | ||
enum MySerializableEnum { value1, value2, value3 } | ||
class MySerializable extends SerializableObject { | ||
MySerializable() { | ||
deserializers['my-list'] = () => <String>[]; | ||
deserializers['my-serializable'] = () => MySerializable(); | ||
transformers['my-enum'] = (value) => value is MySerializableEnum | ||
? value.index | ||
: MySerializableEnum.values[value]; | ||
} | ||
MySerializableEnum get myEnum => attributes['my-enum']; | ||
set myEnum(MySerializableEnum value) => attributes['my-enum'] = value; | ||
int get myNumber => attributes['my-number']; | ||
set myNumber(int value) => attributes['my-number'] = value; | ||
String get myText => attributes['my-text']; | ||
set myText(String value) => attributes['my-text'] = value; | ||
List<String> get myList => attributes['my-list']; | ||
set myList(List<String> value) => attributes['my-list'] = value; | ||
MySerializable get myChild => attributes['my-serializable']; | ||
set myChild(MySerializable value) => attributes['my-serializable'] = value; | ||
} | ||
void main() { | ||
final json = serialize(); | ||
print('seralized: $json'); | ||
final deserialized = deserialize(json); | ||
print('deserialized: $deserialized'); | ||
} | ||
String serialize() { | ||
final child = MySerializable() | ||
..myText = 'hi this is the child element' | ||
..myNumber = 23 | ||
..myChild = null; | ||
final parent = MySerializable() | ||
..myNumber = 13 | ||
..myEnum = MySerializableEnum.value2 | ||
..myText = 'Hello "World"' | ||
..myList = ['one', 'two', 'three'] | ||
..myChild = child; | ||
final serializer = Serializer(); | ||
final json = serializer.serialize(parent); | ||
return json; | ||
} | ||
MySerializable deserialize(String json) { | ||
final serializer = Serializer(); | ||
final mySerializable = MySerializable(); | ||
serializer.deserialize(json, mySerializable); | ||
return mySerializable; | ||
} | ||
``` | ||
|
||
## Features and bugs | ||
|
||
Please file feature requests and bugs at the [issue tracker][tracker]. | ||
|
||
[tracker]: https://github.com/Enough-Software/enough_serialization/issues | ||
|
||
## License | ||
|
||
Licensed under the [MIT License](LICENSE). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Defines a default set of lint rules enforced for | ||
# projects at Google. For details and rationale, | ||
# see https://github.com/dart-lang/pedantic#enabled-lints. | ||
include: package:pedantic/analysis_options.yaml | ||
|
||
# For lint rules and documentation, see http://dart-lang.github.io/linter/lints. | ||
# Uncomment to specify additional rules. | ||
# linter: | ||
# rules: | ||
# - camel_case_types | ||
|
||
analyzer: | ||
# exclude: | ||
# - path/to/excluded/files/** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import 'package:enough_serialization/enough_serialization.dart'; | ||
|
||
enum MySerializableEnum { value1, value2, value3 } | ||
|
||
class MySerializable extends SerializableObject { | ||
MySerializable() { | ||
deserializers['my-list'] = () => <String>[]; | ||
deserializers['my-serializable'] = () => MySerializable(); | ||
transformers['my-enum'] = (value) => value is MySerializableEnum | ||
? value.index | ||
: MySerializableEnum.values[value]; | ||
} | ||
|
||
MySerializableEnum get myEnum => attributes['my-enum']; | ||
set myEnum(MySerializableEnum value) => attributes['my-enum'] = value; | ||
|
||
int get myNumber => attributes['my-number']; | ||
set myNumber(int value) => attributes['my-number'] = value; | ||
|
||
String get myText => attributes['my-text']; | ||
set myText(String value) => attributes['my-text'] = value; | ||
|
||
List<String> get myList => attributes['my-list']; | ||
set myList(List<String> value) => attributes['my-list'] = value; | ||
|
||
MySerializable get myChild => attributes['my-serializable']; | ||
set myChild(MySerializable value) => attributes['my-serializable'] = value; | ||
} | ||
|
||
void main() { | ||
final json = serialize(); | ||
print('seralized: $json'); | ||
final deserialized = deserialize(json); | ||
print('deserialized: $deserialized'); | ||
} | ||
|
||
String serialize() { | ||
final child = MySerializable() | ||
..myText = 'hi this is the child element' | ||
..myNumber = 23 | ||
..myChild = null; | ||
final parent = MySerializable() | ||
..myNumber = 13 | ||
..myEnum = MySerializableEnum.value2 | ||
..myText = 'Hello "World"' | ||
..myList = ['one', 'two', 'three'] | ||
..myChild = child; | ||
final serializer = Serializer(); | ||
final json = serializer.serialize(parent); | ||
return json; | ||
} | ||
|
||
MySerializable deserialize(String json) { | ||
final serializer = Serializer(); | ||
final mySerializable = MySerializable(); | ||
serializer.deserialize(json, mySerializable); | ||
return mySerializable; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/// Support for doing something awesome. | ||
/// | ||
/// More dartdocs go here. | ||
library enough_serialization; | ||
|
||
export 'src/serializable.dart'; | ||
|
||
// TODO: Export any libraries intended for clients of this package. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// TODO: Put public facing types in this file. | ||
|
||
/// Checks if you are awesome. Spoiler: you are. | ||
class Awesome { | ||
bool get isAwesome => true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// Problems: | ||
// - how to create class for a nested objects when de-serializing? | ||
// -> possible solution: create "Serializable Function creator(String name)" | ||
// -> but what if there are several hierarchies of nested objects? | ||
|
||
import 'dart:convert'; | ||
|
||
abstract class Serializable { | ||
Map<String, dynamic> get attributes; | ||
Map<String, dynamic Function(dynamic)> get transformers; | ||
Map<String, dynamic Function()> get deserializers; | ||
} | ||
|
||
class SerializableObject implements Serializable { | ||
final Map<String, dynamic> _attributes = {}; | ||
final Map<String, dynamic Function(dynamic)> _transformers = {}; | ||
final Map<String, dynamic Function()> _deserializers = {}; | ||
|
||
@override | ||
Map<String, dynamic> get attributes => _attributes; | ||
|
||
@override | ||
Map<String, dynamic Function()> get deserializers => _deserializers; | ||
|
||
@override | ||
Map<String, dynamic Function(dynamic)> get transformers => _transformers; | ||
} | ||
|
||
class Serializer { | ||
String serialize(Serializable serializable) { | ||
final buffer = StringBuffer(); | ||
_serializeAttributes(serializable, serializable.attributes, buffer); | ||
return buffer.toString(); | ||
} | ||
|
||
void deserialize(String jsonText, Serializable object) { | ||
final decoder = JsonDecoder(); | ||
final json = decoder.convert(jsonText) as Map<String, dynamic>; | ||
_deserializeAttributes(json, object); | ||
} | ||
|
||
void _serializeAttributes(Serializable parent, | ||
final Map<String, dynamic> attributes, final StringBuffer buffer) { | ||
buffer.write('{'); | ||
var writeSeparator = false; | ||
for (final key in attributes.keys) { | ||
if (writeSeparator) { | ||
buffer.write(', '); | ||
} | ||
buffer..write('"')..write(key)..write('": '); | ||
final value = attributes[key]; | ||
_serializeValue(parent, key, value, buffer); | ||
writeSeparator = true; | ||
} | ||
buffer.write('}'); | ||
} | ||
|
||
void _serializeValue(Serializable parent, final String key, | ||
final dynamic value, final StringBuffer buffer) { | ||
if (value == null) { | ||
buffer.write('null'); | ||
} else if (value is String) { | ||
final text = value.replaceAll('"', r'\"'); | ||
buffer..write('"')..write(text)..write('"'); | ||
} else if (value is int) { | ||
buffer.write(value); | ||
} else if (value is double) { | ||
buffer.write(value); | ||
} else if (value is bool) { | ||
buffer.write(value); | ||
} else if (value is List) { | ||
var writeSeparator = false; | ||
buffer.write('['); | ||
for (final child in value) { | ||
if (writeSeparator) { | ||
buffer.write(', '); | ||
} | ||
_serializeValue(parent, key, child, buffer); | ||
writeSeparator = true; | ||
} | ||
buffer.write(']'); | ||
} else if (value is Serializable) { | ||
_serializeAttributes(value, value.attributes, buffer); | ||
} else { | ||
final transform = parent.transformers[key]; | ||
if (transform == null) { | ||
throw StateError( | ||
'Invalid value encountered, unable to serialize: "$key": $value'); | ||
} | ||
final transformedValue = transform(value); | ||
_serializeValue(parent, key, transformedValue, buffer); | ||
} | ||
} | ||
|
||
void _deserializeAttributes( | ||
final Map<String, dynamic> json, final Serializable object, | ||
[String parentKey]) { | ||
for (final key in json.keys) { | ||
final value = json[key]; | ||
object.attributes[key] = _deserializeValue(object, key, value); | ||
} | ||
} | ||
|
||
dynamic _deserializeValue( | ||
final Serializable parent, final String key, dynamic value) { | ||
final transform = parent.transformers[key]; | ||
if (transform != null) { | ||
return transform(value); | ||
} | ||
if (value is String || value is int || value is double || value is bool) { | ||
return value; | ||
} else if (value is List) { | ||
final function = parent.deserializers[key]; | ||
if (function == null) { | ||
throw StateError( | ||
'Deserialization Warning: no deserializer for List "$key" defined.'); | ||
} | ||
final listValue = function(); | ||
for (final subValue in value) { | ||
listValue.add(_deserializeValue(parent, key, subValue)); | ||
} | ||
return listValue; | ||
} else if (value is Map<String, dynamic>) { | ||
// this is a complex object | ||
final function = parent.deserializers[key]; | ||
if (function == null) { | ||
throw StateError( | ||
'Deserialization Warning: no deserializer for object "$key" defined.'); | ||
} | ||
final serializable = function() as Serializable; | ||
if (serializable == null) { | ||
throw StateError( | ||
'Deserialization Warning: deserializer for object "$key" creates non-serializable object${function()}.'); | ||
} | ||
_deserializeAttributes(value, serializable, key); | ||
return serializable; | ||
} else { | ||
throw StateError( | ||
'Unsupported type ${value.runtimeType} for element "$key".'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
name: enough_serialization | ||
description: Runtime solution for serializing and deserialzing JSON. | ||
version: 1.0.0 | ||
homepage: https://www.github.com/enough-software/enough_serialization | ||
|
||
environment: | ||
sdk: '>=2.9.3 <3.0.0' | ||
|
||
#dependencies: | ||
# path: ^1.7.0 | ||
|
||
dev_dependencies: | ||
pedantic: ^1.9.0 | ||
test: ^1.14.4 |
Oops, something went wrong.