ci: compile the manual
[nit.git] / lib / serialization / README.md
index 4cbcf64..3832465 100644 (file)
@@ -1,11 +1,11 @@
 # Abstract serialization services
 
 # 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 `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.
 
 ~~~
 triggers the generation of customized serialization and deserialization services.
 
 ~~~
@@ -13,7 +13,7 @@ import serialization
 
 # Simple serializable class identifying a human
 class Person
 
 # Simple serializable class identifying a human
 class Person
-       auto_serializable
+       serialize
 
        # First and last name
        var name: String
 
        # 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.
 
 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.
 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`.
 
 ~~~
 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
 class Partnership
-       auto_serializable
+       serialize
 
        var partner_a: Person
        var partner_b: Person
 
        var partner_a: Person
        var partner_b: Person
@@ -51,16 +51,83 @@ class Partnership
        redef fun ==(o) do return o isa SELF and partner_a == o.partner_a and partner_b == o.partner_b
        redef fun hash do return partner_a.hash + 1024*partner_b.hash
 end
        redef fun ==(o) do return o isa SELF and partner_a == o.partner_a and partner_b == o.partner_b
        redef fun hash do return partner_a.hash + 1024*partner_b.hash
 end
+class Person
+end
+~~~
+
+### 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.
+
+  ~~~nitish
+  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
 
 
-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`.
+       # 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
 
 
 ## 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`.
 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 +139,7 @@ The method should only act on known class names, and call super otherwise.
 
 ### Example: the User class
 
 
 ### 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
 because some of the arguments to the `User` class need special treatment:
 
 * The `name` attribute is perfectly normal, it can be serialized and deserialized
@@ -90,7 +157,7 @@ For this customization, the following code snippet implements
 two serialization services: `User::core_serialize_to` and
 `Deserializer::deserialize_class`.
 
 two serialization services: `User::core_serialize_to` and
 `Deserializer::deserialize_class`.
 
-~~~
+~~~nitish
 module user_credentials
 
 # User credentials for a website
 module user_credentials
 
 # User credentials for a website
@@ -160,7 +227,7 @@ information on the services to redefine.
 
 ## Serialization services
 
 
 ## 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`.
 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`.
@@ -168,8 +235,8 @@ you must use implementations of `Serializer` and `Deserializer`.
 The main implementations of these services are `JsonSerializer` and `JsonDeserializer`,
 from the `json_serialization` module.
 
 The main implementations of these services are `JsonSerializer` and `JsonDeserializer`,
 from the `json_serialization` module.
 
-~~~
-import json_serialization
+~~~nitish
+import json
 import user_credentials
 
 # Data to be serialized and deserialized
 import user_credentials
 
 # Data to be serialized and deserialized
@@ -195,22 +262,12 @@ assert couple == deserialize_couple
 
 The serialization has some limitations:
 
 
 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
   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.
 
   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.
 * 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 +275,7 @@ The serialization has some limitations:
   the different programs sharing the serialized data.
 
 * The serialization support in the compiler need some help to
   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
   the next section explores this subject.
 
 ## Dealing with generic types