tests: add some runtime error in nitin.input
[nit.git] / lib / serialization / README.md
index 4cbcf64..3f6ac6c 100644 (file)
@@ -1,11 +1,11 @@
 # Abstract serialization services
 
-The serialization services are centered around the `auto_serializable` annotation,
+The serialization services are based on the `serialize` and the `noserialize` annotations,
 the `Serializable` interface and the implementations of `Serializer` and `Deserializer`.
 
-## The `auto_serializable` annotation
+## The `serialize` annotation
 
-A class annotated with `auto_serializable` identifies it as a subclass of Serializable and
+A class annotated with `serialize` identifies it as a subclass of Serializable and
 triggers the generation of customized serialization and deserialization services.
 
 ~~~
@@ -13,7 +13,7 @@ import serialization
 
 # Simple serializable class identifying a human
 class Person
-       auto_serializable
+       serialize
 
        # First and last name
        var name: String
@@ -31,19 +31,19 @@ By definition of a serializable class, an instance can be serialized to a stream
 The deserialized instance will not be the same instance, but they should be equal.
 So, in this case, we can compare both instances with `==` to test their equality.
 
-Some conditions applies to the classes that can be annotated as `auto_serializable`.
+Some conditions applies to the classes that can be annotated as `serialize`.
 All attributes of the class must be serializable, runtime errors will be
 raised when trying to serialize non-serializable attributes.
 
 In the class `Person`, all attributes are typed with classes the standards library.
 These common types are defined defined as serializable by this project.
-The attributes could also be typed with user-defined `auto_serializable`
+The attributes could also be typed with user-defined `serialize`
 classes or any other subclass of `Serializable`.
 
 ~~~
-# This `auto_serializable` class is composed of two `auto_serializable` attributes
+# This `serialize` class is composed of two `serialize` attributes
 class Partnership
-       auto_serializable
+       serialize
 
        var partner_a: Person
        var partner_b: Person
@@ -53,14 +53,79 @@ class Partnership
 end
 ~~~
 
-The `auto_serializable` applies only to the class definition,
-only attributes declared locally will be serialized.
-However, each definition of a class (a refinement or specialization)
-can declare `auto_serializable`.
+### Scope of the `serialize` annotation
+
+`serialize` can annotate class definitions, modules and attributes:
+
+* The annotation on a class applies only to the class definition,
+  only attributes declared locally will be serialized.
+  However, each definition of a class (a refinement or specialization) can be annotated with `serialize`.
+
+* A module declaration annotated with `serialize` states that all its class definitions
+  and locally declared attributes are serializable.
+
+  ~~~
+  module shared_between_clients is serialize
+  ~~~
+
+* Attribute annotated with `serialize` states that it is to be serialized, when the rest of the class does not.
+  The class will become subclass to `Serializable` but its attributes are not to be serialized by default.
+  Only the attributes with the `serialize` annotation will be serialized.
+
+  ~~~
+  # Only serialize the `name`
+  class UserCredentials
+      var name: String is serialize
+      var avatar_path: String = "/somepath/"+name is lazy
+  end
+  ~~~
+
+## The `noserialize` annotation
+
+The `noserialize` annotation mark an exception in a `serialize` module or class definition.
+
+* By default a module is `noserialize`. There is no need to declare it as such.
+
+* A class definition annotated with `noserialize` within a `serialize` module will not be made serializable.
+
+* A `noserialize` attribute within a class or module annotated with `serialize` will not serialize this attribute.
+  The class will still be made subclass of `Serializable` and it won't affect the other attributes.
+  The `noserialize` attribute will not be set at deserialization.
+  Usually, it will also be annotated with `lazy` to get its value by another mean after the object has been deserialized.
+
+  ~~~
+  # Once again, only serialize the `name`
+  class UserCredentials
+      serialize
+
+      var name: String
+      var avatar_path: String = "/somepath/"+name is noserialize, lazy
+  end
+  ~~~
+
+## The `serialize_as` annotation
+
+By default, an attribute is identified in the serialization format by its Nit name.
+The `serialize_as` attribute changes this behavior and sets the name of an attribute in the serialization format.
+
+This annotation can be useful to change the name of an attribute to what is expected by a remote service.
+Or to use identifiers in the serialization format that are reserved keywords in Nit (like `class` and `type`).
+
+~~~
+class UserCredentials
+       serialize
+
+       # Rename to "username" in JSON for compatibility with remote service
+       var name: String is serialize_as "username"
+
+       # Rename to a shorter "ap" for a smaller JSON file
+       var avatar_path: String = "/somepath/"+name is lazy, serialize_as "ap"
+end
+~~~
 
 ## Custom serializable classes
 
-The annotation `auto_serializable` should be enough for most cases,
+The annotation `serialize` should be enough for most cases,
 but in some cases you need more control over the serialization process.
 
 For more control, create a subclass to `Serializable` and redefine `core_serialize_to`.
@@ -72,7 +137,7 @@ The method should only act on known class names, and call super otherwise.
 
 ### Example: the User class
 
-The following example cannot use the `auto_serializable` annotations
+The following example cannot use the `serialize` annotations
 because some of the arguments to the `User` class need special treatment:
 
 * The `name` attribute is perfectly normal, it can be serialized and deserialized
@@ -160,7 +225,7 @@ information on the services to redefine.
 
 ## Serialization services
 
-The `auto_serializable` annotation and the `Serializable` class are used on
+The `serialize` annotation and the `Serializable` class are used on
 classes specific to the business domain.
 To write (and read) instances of these classes to a persistent format
 you must use implementations of `Serializer` and `Deserializer`.
@@ -169,7 +234,7 @@ The main implementations of these services are `JsonSerializer` and `JsonDeseria
 from the `json_serialization` module.
 
 ~~~
-import json_serialization
+import json
 import user_credentials
 
 # Data to be serialized and deserialized
@@ -195,22 +260,12 @@ assert couple == deserialize_couple
 
 The serialization has some limitations:
 
-* Not enough classes from the standard library are supported.
-  This only requires someone to actually code the support.
-  It should not be especially hard for most classes, some can
-  simply declare the `auto_serializable` annotation.
-
-* A limitation of the Json parser prevents deserializing from files
+* A limitation of the JSON parser prevents deserializing from files
   with more than one object.
   This could be improved in the future, but for now you should
-  serialize a single object to each filesand use different instances of
+  serialize a single object to each files and use different instances of
   serializer and deserializer each time.
 
-* The `auto_serializable` annotation does not handle very well
-  complex constructors. This could be improved in the compiler.
-  For now, you may prefer to use `auto_serializable` on simple classes,
-  of by using custom `Serializable`.
-
 * The serialization uses only the short name of a class, not its qualified name.
   This will cause problem when different classes using the same name.
   This could be solved partially in the compiler and the library.
@@ -218,7 +273,7 @@ The serialization has some limitations:
   the different programs sharing the serialized data.
 
 * The serialization support in the compiler need some help to
-  deal with generic types. The solution is to use `nitserial`,
+  deal with generic types. A solution is to use `nitserial`,
   the next section explores this subject.
 
 ## Dealing with generic types