Git Product home page Git Product logo

serialization.dart's Introduction

General serialization for Dart objects.

Build Status

Save and restore objects flexibly.

This can serialize and de-serialize objects to multiple different formats. It is most useful if you have Dart on both ends, rather than needing to communicate with an external system. It can handle cycles, inheritance, getters and setters, private or final fields set via constructors, objects serialized in different ways at different times, and other complex options. It can handle serializing acyclic objects with only public fields to a simple JSON format, but might be more heavyweight than is necessary if that's the only requirement.

This has no privileged access to object representations, so objects are accessed and created according to their public APIs. As a result, serializations from older versions where the internal representation has changed can still be read as long as the public API is still available.

The way an object's state is read and written is defined by SerializationRules. These can be implemented in various ways. The easiest to use is using mirrors to find the members. Rules can also be hand-written or, for relatively simple classes, generated using a transformer.

Usage

Import either

import "package:serialization/serialization.dart"

or

import "package:serialization/serialization_mirrors.dart"

depending on whether or not you want the mirrored rules. These are more convenient, but cause increased code size in dartj2s.

To use the transformer, include something in the pubspec like

 transformers:
   - serialization :
     $include: ["lib/stuff.dart", "lib/more_stuff.dart"]

Then, set up the generated rules in a Serialization instance, and then call write(). The serialization rules will be named as the name of the model file with _serialization_rules appended to it, so in the case of stuff.dart, stuff_serialization_rules.dart, in the same directory as the original.

Normally you won't ever see these files, because the transformer creates it on the fly and it is sent directly to pub serve or to dart2js without ever being written to disk. To see the generated code, run pub build in debug mode, e.g. if there is a program in the package's bin directory to run something using these files, then

pub build --mode=debug bin

would generate the code for that, and also log which files were generated, in the form

Generated serialization rules in my_package|lib/stuff_serialization_rules.dart

It's also possible to run the transformer's code outside of the transformer, which is helpful for debugging or to use the code in a different way. See the `test/transformer/generate_standalone.dart' for an example of that.

The bin directory code would look something like.

import 'package:my_package/stuff_serialization_rules.dart' as foo;
 ...
 var serialization = new Serialization();
 foo.rules.values.forEach(serialization.addRule);
 ...
 sendToClient(serialization.write(somePerson));

and on the client, do something like

 p = readFromServer(personId).then((data) => serialization.read(data));

Alternatively, if using the mirrored rules, just tell the serialization which classes might be serialized.

  var serialization = new Serialization()
    ..addRuleFor(Person);
    ..addRuleFor(Address);
  serialization.write(address);

For more concrete examples, see the test directory, and particularly for examples of the transformer it may be useful to look at the pubspec.yaml for this package, and thetest/transformer directory.

Requests and bugs

Please file feature requests and bugs via the GitHub Issue Tracker. This is licensed under the same license as Dart

Disclaimer

This is not an official Google project.

serialization.dart's People

Contributors

alan-knight avatar cbracken avatar gazialankus avatar sethladd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serialization.dart's Issues

Part of files not handled

Say I have a file my_lib.dart that specifies two other files using the part directive, part_a.dart and part_b.dart. I can successfully generate part_a_serialization_rules.dart and part_b_serialization_rules.dart using the transformer. However when I try to import these generated files they throw an exception. If I import part_a_serialization_rules.dart it will in turn import part_a.dart which has a "part of my_lib" as a first line which will not work because you cannot import a part by itself.

Support datetime serialisation in a standard string format

(I've seen there's a DateTimeRule, but it says "A hard-coded rule for DateTime", so it's not clear to me how (or if) I can override it).

Currently when serialising something with DateTimes, I get this:

{
  name: 'Danny',
  startDateUtc: [1414781347884, false]
}

This is messy to interop with other services; many of which just use a standard string format for dates like yyyy-MM-ddTHH:mm:ss. It would be good if we could set a custom format on the serializer for this.

How do I cause the transformer to run and generate rules?

I'm trying to use this, but I'm failing to follow the Usage in the Readme :(

I have generated a bunch of Dart types from C# code; these live in lib/src/blah/types.dart. I have added this to the file where I wish to do serialization:

import "package:serialization/serialization.dart"

I have added the following to my pubspec.yaml:

dependencies:
  serialization: any
transformers:
  - serialization:
      $include: ["lib/src/blah/types.dart"]

The next thing in the readme says:

and set up the generated rules in a Serialization instance, on which you can then call write().

import 'package:my_package/stuff_serialization_rules.dart' as foo;

However it's not clear to me what this filename is. How do I cause the transformer to run? (I ran pub build but that didn't seem to generate anything). Where do I set/get this filename? I'm developing with Dartium, so I want Dart rules for now. I'm not using pub serve because it's too limited; so I need something to dump the rules onto a Dart file on disk via a one-off command that I can run whenever the classes are updated.

reduce limitations

The limitations listed in the transformation doco effectively render it useless for me. I very often have multiple constructors, use inheritance and have mostly immutable classes where the constructors contain some logic.

Are there any plans to improve this? In particular, provide a way to specify the constructors to use. One way is via annotations. Another would be to allow defaults to be specified. e.g. default to always calling the unnamed constructor, or a constructor called say 'build'.

FYI I do support such features in shelf_bind and it wasn't overly complex from memory, but that was with mirrors - I haven't tried transformers yet - maybe that is trickier?

Limitations
Note that this is quite limited. It does not handle inheritance at all. If constructors have parameters which are not of the form "this.field", those will always be passed as null. It will always use the constructor with the fewest parameters. It does handle getter/setter pairs and getters or fields which correspond to constructor parameters. It will probably not work with part files, and it expects all the classes that will be serialized to be listed in those files.

Make serialization.dart compatible with Dart editor

I am not a dart expert and I may be wrong, but it seems like the lines such as

import 'package:mypackage/myclass_serialization_rules.dart';

appear as errors in the Dart editor are underlined in red. However, it seems to work fine when ran. These apparent errors are an annoyance for the programmer.

Would there be at least a workaround not to see these errors and have serialization.dart be compatible with the Dart editor?

Alternatively, is there a bug report in Dart editor to make this happen?

Thanks.

Sample code doesn't appear to work; mismatch in args?

In the docs there are samples like this:

Map output = serialization.write(address, new SimpleMapFormat());
List output = serialization.write(address, new SimpleFlatFormat());
var output = serialization.write(address, new SimpleJsonFormat());

However these don't seem to run; I get methodMissing, unless I provide a name for the format arg:

var output = serialization.write(address, format: new SimpleJsonFormat());

Using sets does not work

I'm using the transformers with import '..._serialization_rules.dart'. I'm not supplying a format field to the Serialization constructor to use the default.

Lists and Maps are serialized just fine. Sets aren't. I get the below stacktrace when trying to serialize an object that has a Set.

Exception: Uncaught Error: Unsupported operation: Attempted to serialize type without a defined rule {}. This is not supported in basic serialization, either define a rule for this type or use serialization_mirrors
Stack Trace:
#0      Serialization.addRuleFor (package:serialization/serialization.dart:309:6)
#1      Serialization.rulesFor (package:serialization/serialization.dart:426:34)
#2      Writer._process (package:serialization/src/reader_writer.dart:109:48)
#3      Trace.traceAll (package:serialization/src/reader_writer.dart:536:47)
#4      Writer.write (package:serialization/src/reader_writer.dart:76:19)
#5      Serialization.write (package:serialization/serialization.dart:353:35)

Any suggestions?

Serializartion rules not working in Checked mode

It seems that when I try to serialize an object using the Serialization package in checked mode I get the following Error:

Unhandled exception:
type '_LinkedHashMap' is not a subtype of type 'String' of 'personJson'.
#0      main (file:///Users/nivco/GoogleDrive/workspace/serialization-sample/isolates_serialization/build/bin/isolates_serialization.dart:20:42)
#1      _startIsolate (dart:isolate-patch/isolate_patch.dart:239)
#2      _startMainIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:192)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:130)

You'll find the code to replicate attached to this issue: https://code.google.com/p/dart/issues/detail?id=21824

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.