add resolve_namespace_type + use va_list in register.add_type

This commit is contained in:
a-Sansara 2018-08-20 03:38:31 +02:00
parent 7315d2cba2
commit 6b77c25111
6 changed files with 170 additions and 45 deletions

108
README.md
View File

@ -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). 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** 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_ : ![pluie-yaml-2](https://www.meta-tech.academy/img/pluie-yaml-2.png)
```
[ 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;
```
## License ## License
@ -135,6 +118,34 @@ see Finder below to get precisions about config.get parameter (search path defin
db : db.yml 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 ### loader
@ -330,14 +341,17 @@ public class Example : Yaml.Object
{ {
static construct static construct
{ {
Yaml.Object.register.add_type (typeof (Example), typeof (ExampleStruct)); Yaml.Object.register.add_type (
Yaml.Object.register.add_type (typeof (Example), typeof (Gee.ArrayList)); 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. Secondly you must override the `public void populate_from_node (Glib.Type, Yaml.Node node)` Yaml.Object original method.
`populate_by_type` is called by the Yaml.Builder only if the type property is prealably registered. `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` : 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) ![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 ### more samples

View File

@ -44,8 +44,12 @@ int main (string[] args)
var config = new Yaml.Config (path, true); var config = new Yaml.Config (path, true);
var root = config.root_node (); var root = config.root_node ();
root.display_childs (); 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); var n = Yaml.Builder.to_node (obj);
if ((done = n !=null)) { if ((done = n !=null)) {
n.display_childs (); n.display_childs ();

View File

@ -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)) { 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); var child = obj.populate_to_node(def.value_type, name);
if (child != null) { if (child != null) {
child.tag = new Yaml.Tag (Yaml.Object.register.resolve_namespace_type(def.value_type), "v");
node.add (child); node.add (child);
} }
} }
@ -338,7 +339,7 @@ public class Pluie.Yaml.Builder
obj.get (name, out enumval); obj.get (name, out enumval);
string data = enumval.value.to_string (); string data = enumval.value.to_string ();
var n = new Yaml.Mapping.with_scalar (node, name, (string) data); 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 ()) { 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) { if (root) {
var rootNode = new Yaml.Root(); var rootNode = new Yaml.Root();
rootNode.add (node); rootNode.add (node);

View File

@ -68,8 +68,11 @@ public class Pluie.Yaml.Example : Yaml.Object
static construct static construct
{ {
Yaml.Object.register.add_type (typeof (Yaml.Example), typeof (Yaml.ExampleStruct)); Yaml.Object.register.add_type (
Yaml.Object.register.add_type (typeof (Yaml.Example), typeof (Gee.ArrayList)); 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); new Yaml.Scalar (node, data);
} }
} }
node.tag = new Yaml.Tag (type.name (), "v");
} }
return node; return node;
} }

View File

@ -57,6 +57,7 @@ public abstract class Pluie.Yaml.Object : GLib.Object
{ {
register = new Yaml.Register(); register = new Yaml.Register();
yaml_tag = new Tag (typeof (Pluie.Yaml.Object).name (), "v"); yaml_tag = new Tag (typeof (Pluie.Yaml.Object).name (), "v");
register.add_namespace("Pluie", "Pluie.Yaml", "Gee");
} }
/** /**

View File

@ -40,13 +40,18 @@ public class Pluie.Yaml.Register : GLib.Object
/** /**
* *
*/ */
public static Gee.HashMap<Type, Gee.ArrayList<GLib.Type>> reg { get; internal set; } public static Gee.HashMap<Type, Gee.ArrayList<GLib.Type>> rtype { get; internal set; }
/**
*
*/
public static Gee.ArrayList<string> namespaces { get; internal set; }
/** /**
* *
*/ */
static construct { static construct {
Yaml.Register.reg = new Gee.HashMap<Type, Gee.ArrayList<GLib.Type>> (); Yaml.Register.rtype = new Gee.HashMap<Type, Gee.ArrayList<GLib.Type>> ();
Yaml.Register.namespaces = new Gee.ArrayList<string> ();
} }
/** /**
@ -60,20 +65,82 @@ public class Pluie.Yaml.Register : GLib.Object
/** /**
* *
*/ */
public Gee.ArrayList<GLib.Type>? 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)) { var name = type.name ();
reg.set (type, this.init_type_list ()); 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];
} }
return reg.get (type).add (addedType); }
// case ENUM which ends with dot
if (rn.substring(-1) == ".") {
rn = name.splice (0, gb.length, rn);
}
name = rn;
}
catch (GLib.RegexError e) {
of.error (e.message);
}
Yaml.dbg ("resolve_namespace_type %s => %s".printf (type.name (), name));
return name;
}
/**
*
*/
public Gee.ArrayList<GLib.Type>? 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<GLib.Type> ();
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) 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) 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);
} }
} }