diff --git a/README.md b/README.md index acc961a..4f9f53c 100644 --- a/README.md +++ b/README.md @@ -10,34 +10,17 @@ in the main yaml document. The lib partially manage tag directives and tag values (basic types and Yaml.Object extended objects types). +with version 0.5, **pluie-yaml** is now able to : + +* parse yaml file with vala tags => transform to Yaml.Node +* Build Yaml.Object from Yaml.Node (with some glue for struct and non Yaml.Object derived types) +* Build Yaml.Node from Yaml.Object (with some glue for struct and non Yaml.Object derived types) + **pluie-yaml** use the ![libyaml c library](https://github.com/yaml/libyaml) (License MIT, many thanks to Kirill Simonov) to parse and retriew related yaml events. -![pluie-yaml](https://www.meta-tech.academy/img/pluie-yaml-imports2.png) +![pluie-yaml-1](https://www.meta-tech.academy/img/pluie-yaml-1.png) -_legend display_childs_ : - -``` -[ node.name [refCount] node.parent.name node.level node.ntype.infos () node.count () node.uuid node.tag] -``` - -You can easily manage display tracing of yaml nodes by setting these var according to your needs : - -```vala -namespace Pluie -{ - namespace Yaml - { - public static bool DEBUG = false; - - public static bool DBG_SHOW_INDENT = true; - public static bool DBG_SHOW_PARENT = false; - public static bool DBG_SHOW_UUID = true; - public static bool DBG_SHOW_LEVEL = false; - public static bool DBG_SHOW_REF = false; - public static bool DBG_SHOW_COUNT = true; - public static bool DBG_SHOW_TAG = true; - public static bool DBG_SHOW_TYPE = true; -``` +![pluie-yaml-2](https://www.meta-tech.academy/img/pluie-yaml-2.png) ## License @@ -135,6 +118,34 @@ see Finder below to get precisions about config.get parameter (search path defin db : db.yml ``` +![pluie-yaml](https://www.meta-tech.academy/img/pluie-yaml-imports2.png) + +_legend display_childs_ : + +``` +[ node.name [refCount] node.parent.name node.level node.ntype.infos () node.count () node.uuid node.tag] +``` + +You can easily manage display tracing of yaml nodes by setting these var according to your needs : + +```vala +using Pluie + +... + // general debug display usefull informations + Yaml.DEBUG = false; + // drive display_childs method : + Yaml.DBG_SHOW_INDENT = true; + Yaml.DBG_SHOW_PARENT = false; + Yaml.DBG_SHOW_UUID = true; + Yaml.DBG_SHOW_LEVEL = false; + Yaml.DBG_SHOW_REF = false; + Yaml.DBG_SHOW_COUNT = true; + Yaml.DBG_SHOW_TAG = true; + Yaml.DBG_SHOW_TYPE = true; +... +``` + ------------------- ### loader @@ -330,14 +341,17 @@ public class Example : Yaml.Object { static construct { - Yaml.Object.register.add_type (typeof (Example), typeof (ExampleStruct)); - Yaml.Object.register.add_type (typeof (Example), typeof (Gee.ArrayList)); + Yaml.Object.register.add_type ( + typeof (Yaml.Example), // owned type + typeof (Yaml.ExampleStruct), // property type + typeof (Gee.ArrayList) // property type + ); } ... ``` -Secondly you must override the `Yaml.Object populate_from_node (Glib.Type, Yaml.Node node)` original method. -`populate_by_type` is called by the Yaml.Builder only if the type property is prealably registered. +Secondly you must override the `public void populate_from_node (Glib.Type, Yaml.Node node)` Yaml.Object original method. +`populate_from_node` is automatically called by the Yaml.Builder if the type property is prealably registered. Example of implementation from `src/vala/Pluie/Yaml.Example.vala` : @@ -374,6 +388,42 @@ output from samples/yaml-tag.vala : ![pluie-yaml-tag](https://www.meta-tech.academy/img/pluie-yaml-sample-tag-output.png?tmp=53) + +### Build Yaml.Node from Yaml.Object + +reverse build mechanism is also possible but have the same limitation. +you need to override the `public Yaml.Node? populate_to_node(GLib.Type type, string name)` Yaml.Object original method +`populate_to_node` is also automatically called by the Yaml.Builder if the type property is prealably registered. + +Example of implementation from `src/vala/Pluie/Yaml.Example.vala` : + +```vala + public override Yaml.Node? populate_to_node(GLib.Type type, string name) + { + Yaml.Node? node = base.populate_to_node (type, name); + // non Yaml.Object type & registered type + if (node == null) { + if (type == typeof (Yaml.ExampleStruct)) { + node = new Yaml.Mapping (null, name); + new Yaml.Mapping.with_scalar (node, "red" , this.type_struct.red.to_string ()); + new Yaml.Mapping.with_scalar (node, "green", this.type_struct.green.to_string ()); + new Yaml.Mapping.with_scalar (node, "blue" , this.type_struct.blue.to_string ()); + } + else if (type == typeof (Gee.ArrayList)) { + node = new Yaml.Sequence (null, name); + foreach (var data in this.type_gee_al) { + new Yaml.Scalar (node, data); + } + } + } + return node; + } +``` + +for more details see : +* `samples/yaml-tonode.vala` + + ------------------- ### more samples diff --git a/samples/yaml-tonode.vala b/samples/yaml-tonode.vala index fe68969..5defbbb 100644 --- a/samples/yaml-tonode.vala +++ b/samples/yaml-tonode.vala @@ -44,8 +44,12 @@ int main (string[] args) var config = new Yaml.Config (path, true); var root = config.root_node (); root.display_childs (); - var obj = (Yaml.Example) Yaml.Builder.from_node (root.first ()); + of.action ("Yaml.Builder.from_node", root.first ().name); + var obj = (Yaml.Example) Yaml.Builder.from_node (root.first ()); + obj.type_object.method_a (); + + of.action ("Yaml.Builder.to_node", obj.get_type ().name ()); var n = Yaml.Builder.to_node (obj); if ((done = n !=null)) { n.display_childs (); diff --git a/src/vala/Pluie/Yaml.Builder.vala b/src/vala/Pluie/Yaml.Builder.vala index f0eeef0..1d5e7c1 100644 --- a/src/vala/Pluie/Yaml.Builder.vala +++ b/src/vala/Pluie/Yaml.Builder.vala @@ -330,6 +330,7 @@ public class Pluie.Yaml.Builder if (def.value_type.is_a (typeof (Yaml.Object)) || Yaml.Object.register.is_registered_type(obj.get_type (), def.value_type)) { var child = obj.populate_to_node(def.value_type, name); if (child != null) { + child.tag = new Yaml.Tag (Yaml.Object.register.resolve_namespace_type(def.value_type), "v"); node.add (child); } } @@ -338,7 +339,7 @@ public class Pluie.Yaml.Builder obj.get (name, out enumval); string data = enumval.value.to_string (); var n = new Yaml.Mapping.with_scalar (node, name, (string) data); - n.tag = new Yaml.Tag (def.value_type.name (), "v"); + n.tag = new Yaml.Tag (Yaml.Object.register.resolve_namespace_type(def.value_type), "v"); } else if (def.value_type.is_fundamental ()) { @@ -352,7 +353,7 @@ public class Pluie.Yaml.Builder } } } - node.tag = new Yaml.Tag (obj.get_type ().name (), "v"); + node.tag = new Yaml.Tag (Yaml.Object.register.resolve_namespace_type(obj.get_type ()), "v"); if (root) { var rootNode = new Yaml.Root(); rootNode.add (node); diff --git a/src/vala/Pluie/Yaml.Example.vala b/src/vala/Pluie/Yaml.Example.vala index 87121e3..c0011e8 100644 --- a/src/vala/Pluie/Yaml.Example.vala +++ b/src/vala/Pluie/Yaml.Example.vala @@ -68,8 +68,11 @@ public class Pluie.Yaml.Example : Yaml.Object static construct { - Yaml.Object.register.add_type (typeof (Yaml.Example), typeof (Yaml.ExampleStruct)); - Yaml.Object.register.add_type (typeof (Yaml.Example), typeof (Gee.ArrayList)); + Yaml.Object.register.add_type ( + typeof (Yaml.Example), + typeof (Yaml.ExampleStruct), + typeof (Gee.ArrayList) + ); } /** @@ -123,7 +126,6 @@ public class Pluie.Yaml.Example : Yaml.Object new Yaml.Scalar (node, data); } } - node.tag = new Yaml.Tag (type.name (), "v"); } return node; } diff --git a/src/vala/Pluie/Yaml.Object.vala b/src/vala/Pluie/Yaml.Object.vala index 6c23c71..34bf4fe 100644 --- a/src/vala/Pluie/Yaml.Object.vala +++ b/src/vala/Pluie/Yaml.Object.vala @@ -57,6 +57,7 @@ public abstract class Pluie.Yaml.Object : GLib.Object { register = new Yaml.Register(); yaml_tag = new Tag (typeof (Pluie.Yaml.Object).name (), "v"); + register.add_namespace("Pluie", "Pluie.Yaml", "Gee"); } /** diff --git a/src/vala/Pluie/Yaml.Register.vala b/src/vala/Pluie/Yaml.Register.vala index ddd4332..758ef4b 100644 --- a/src/vala/Pluie/Yaml.Register.vala +++ b/src/vala/Pluie/Yaml.Register.vala @@ -40,13 +40,18 @@ public class Pluie.Yaml.Register : GLib.Object /** * */ - public static Gee.HashMap> reg { get; internal set; } + public static Gee.HashMap> rtype { get; internal set; } + /** + * + */ + public static Gee.ArrayList namespaces { get; internal set; } /** * */ static construct { - Yaml.Register.reg = new Gee.HashMap> (); + Yaml.Register.rtype = new Gee.HashMap> (); + Yaml.Register.namespaces = new Gee.ArrayList (); } /** @@ -60,20 +65,82 @@ public class Pluie.Yaml.Register : GLib.Object /** * */ - public Gee.ArrayList? get_type_list (GLib.Type type) + public bool add_namespace (string name, ...) { - return reg.get (type); + var l = va_list(); + Yaml.dbg ("adding namespace %s".printf (name)); + var done = Yaml.Register.namespaces.contains (name) || Yaml.Register.namespaces.add (name); + while (done) { + string? ns = l.arg(); + if (ns == null) { + break; // end of the list + } + Yaml.dbg ("adding namespace %s".printf (ns)); + if (!Yaml.Register.namespaces.contains (ns)) { + done = done && Yaml.Register.namespaces.add (ns); + } + } + return done; } /** * */ - public bool add_type (GLib.Type type, GLib.Type addedType) + public string resolve_namespace_type (GLib.Type type) { - if (!this.is_registered (type)) { - reg.set (type, this.init_type_list ()); + var name = type.name (); + try { + Regex reg = new Regex ("([A-Z]{1}[a-z]+)"); + var d = reg.split (type.name (), 0); + var rn = ""; + var gb = ""; + for (var i = 1; i < d.length; i+=2) { + rn += d[i]; + if (namespaces.contains (rn)) { + rn += "."; + gb += d[i]; + } + } + // case ENUM which ends with dot + if (rn.substring(-1) == ".") { + rn = name.splice (0, gb.length, rn); + } + name = rn; } - return reg.get (type).add (addedType); + catch (GLib.RegexError e) { + of.error (e.message); + } + Yaml.dbg ("resolve_namespace_type %s => %s".printf (type.name (), name)); + return name; + } + + /** + * + */ + public Gee.ArrayList? get_type_list (GLib.Type type) + { + return rtype.get (type); + } + + /** + * + */ + public bool add_type (GLib.Type owntype, ...) + { + bool done = true; + if (!this.is_registered (owntype)) { + rtype.set (owntype, this.init_type_list ()); + } + var l = va_list(); + while (done) { + GLib.Type? t = l.arg (); + if (t == null || t == Type.INVALID) { + break; + } + Yaml.dbg ("adding to %s type %s".printf (owntype.name (), t.name ())); + done = done && rtype.get (owntype).add (t); + } + return done; } /** @@ -81,7 +148,7 @@ public class Pluie.Yaml.Register : GLib.Object */ public bool is_registered (GLib.Type type) { - return reg.has_key (type); + return rtype.has_key (type); } /** @@ -89,6 +156,6 @@ public class Pluie.Yaml.Register : GLib.Object */ public bool is_registered_type (GLib.Type type, GLib.Type checktype) { - return this.is_registered (type) && reg.get (type).contains (checktype); + return this.is_registered (type) && rtype.get (type).contains (checktype); } }