From 87664f31b4322e940d32ecdd3463761da8166551 Mon Sep 17 00:00:00 2001 From: a-Sansara Date: Sun, 19 Aug 2018 23:15:24 +0200 Subject: [PATCH] provide Yaml.Object to Yaml.Node conversion --- README.md | 4 +- meson.build | 4 +- samples/yaml-tag.vala | 31 ++++---- samples/yaml-tonode.vala | 84 ++++++++++++++++++++ src/vala/Pluie/Yaml.Builder.vala | 104 ++++++++++++++++++++++++- src/vala/Pluie/Yaml.Example.vala | 27 ++++++- src/vala/Pluie/Yaml.ExampleChild.vala | 2 +- src/vala/Pluie/Yaml.ExampleStruct.vala | 21 ++++- src/vala/Pluie/Yaml.Object.vala | 39 +++++++--- valadoc.sh | 1 - 10 files changed, 281 insertions(+), 36 deletions(-) create mode 100644 samples/yaml-tonode.vala diff --git a/README.md b/README.md index a2492ac..acc961a 100644 --- a/README.md +++ b/README.md @@ -336,13 +336,13 @@ public class Example : Yaml.Object ... ``` -Secondly you must override the `Yaml.Object populate_by_type (Glib.Type, Yaml.Node node)` original method. +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. Example of implementation from `src/vala/Pluie/Yaml.Example.vala` : ```vala - public override void populate_by_type(GLib.Type type, Yaml.Node node) + public override void populate_from_node(GLib.Type type, Yaml.Node node) { if (type == typeof (Yaml.ExampleStruct)) { this.type_struct = ExampleStruct.from_yaml_node (node); diff --git a/meson.build b/meson.build index e89a0b9..78fee6b 100644 --- a/meson.build +++ b/meson.build @@ -27,7 +27,7 @@ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -project('libpluie-yaml', 'vala', 'c', version:'0.5') +project('pluie-yaml', 'vala', 'c', version:'0.5') cc = meson.get_compiler('c') dep_glib = dependency('glib-2.0') @@ -41,7 +41,7 @@ dep_yaml = cc.find_library('yaml', required : true) #~ add_global_link_arguments('-lyaml', language : 'c') -version = '0.5' +version = meson.project_version() bindir = join_paths(get_option('prefix'), get_option('bindir')) datadir = join_paths(get_option('prefix'), get_option('datadir'), 'pluie/yaml') libdir = join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig') diff --git a/samples/yaml-tag.vala b/samples/yaml-tag.vala index 817afdd..961e476 100644 --- a/samples/yaml-tag.vala +++ b/samples/yaml-tag.vala @@ -64,21 +64,22 @@ int main (string[] args) Yaml.Example? o = null; foreach (var entry in list.entries) { if ((o = (Yaml.Example) entry.value)!=null) { - of.action ("Getting Hard coded values for Yaml.Object %s".printf (of.c (ECHO.MICROTIME).s (o.type_from_self ())), entry.key); - of.keyval("type_int" , "%d" .printf(o.type_int)); - of.keyval("type_bool" , "%s" .printf(o.type_bool.to_string ())); - of.keyval("type_char" , "%c" .printf(o.type_char)); - of.keyval("type_string", "%s" .printf(o.type_string)); - of.keyval("type_uchar" , "%u" .printf(o.type_uchar)); - of.keyval("type_uint" , "%u" .printf(o.type_uint)); - of.keyval("type_float" , "%f" .printf(o.type_float)); - of.keyval("type_double", "%f" .printf(o.type_double)); - of.keyval("type_struct", "%s" .printf(o.type_struct.to_string ())); - of.keyval("type_object", "%s" .printf(o.type_object.get_type ().name ())); - of.keyval(" toto" , "%s (string)" .printf(o.type_object.toto)); - of.keyval(" tapa" , "%s (string)" .printf(o.type_object.tata)); - of.keyval(" titi" , "%d (int)" .printf(o.type_object.titi)); - of.keyval(" tutu" , "%s (bool)" .printf(o.type_object.tutu.to_string ())); + of.action ("Getting Hard coded values for Yaml.Object %s".printf (of.c (ECHO.MICROTIME).s (o.get_type().name ())), entry.key); + of.keyval("yaml_name" , "%s" .printf(o.yaml_name)); + of.keyval("type_int" , "%d" .printf(o.type_int)); + of.keyval("type_bool" , "%s" .printf(o.type_bool.to_string ())); + of.keyval("type_char" , "%c" .printf(o.type_char)); + of.keyval("type_string" , "%s" .printf(o.type_string)); + of.keyval("type_uchar" , "%u" .printf(o.type_uchar)); + of.keyval("type_uint" , "%u" .printf(o.type_uint)); + of.keyval("type_float" , "%f" .printf(o.type_float)); + of.keyval("type_double" , "%f" .printf(o.type_double)); + of.keyval("type_struct" , "%s" .printf(o.type_struct.to_string ())); + of.keyval("type_object" , "%s" .printf(o.type_object.get_type ().name ())); + of.keyval(" toto" , "%s (string)" .printf(o.type_object.toto)); + of.keyval(" tapa" , "%s (string)" .printf(o.type_object.tata)); + of.keyval(" titi" , "%d (int)" .printf(o.type_object.titi)); + of.keyval(" tutu" , "%s (bool)" .printf(o.type_object.tutu.to_string ())); o.type_object.method_a (); if (o.type_gee_al != null) { of.keyval("type_gee_al", "(%s)" .printf(o.type_gee_al.get_type ().name ())); diff --git a/samples/yaml-tonode.vala b/samples/yaml-tonode.vala new file mode 100644 index 0000000..1c2cc7a --- /dev/null +++ b/samples/yaml-tonode.vala @@ -0,0 +1,84 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * @software : pluie-yaml + * @version : 0.5 + * @type : library + * @date : 2018 + * @licence : GPLv3.0 + * @author : a-Sansara <[dev]at[pluie]dot[org]> + * @copyright : pluie.org + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * This file is part of pluie-yaml. + * + * pluie-yaml is free software (free as in speech) : you can redistribute it + * and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * pluie-yaml is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with pluie-yaml. If not, see . + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + + +using GLib; +using Gee; +using Pluie; + +int main (string[] args) +{ + Echo.init(false); + + var path = Yaml.DATA_PATH + "/tag.yml"; + var done = false; + + of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara"); + Pluie.Yaml.DEBUG = false; + 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 ("Getting Hard coded values for Yaml.Object %s".printf (of.c (ECHO.MICROTIME).s (obj.get_type().name ())), obj.yaml_name); + of.keyval("yaml_name" , "%s" .printf(obj.yaml_name)); + of.keyval("type_int" , "%d" .printf(obj.type_int)); + of.keyval("type_bool" , "%s" .printf(obj.type_bool.to_string ())); + of.keyval("type_char" , "%c" .printf(obj.type_char)); + of.keyval("type_string" , "%s" .printf(obj.type_string)); + of.keyval("type_uchar" , "%c" .printf(obj.type_uchar)); + of.keyval("type_uint" , "%u" .printf(obj.type_uint)); + of.keyval("type_float" , "%f" .printf(obj.type_float)); + of.keyval("type_double" , "%f" .printf(obj.type_double)); + of.keyval("type_enum" , "%s" .printf(obj.type_enum.to_string ())); + of.keyval("type_struct" , "%s" .printf(obj.type_struct.to_string ())); + of.keyval("type_object" , "%s" .printf(obj.type_object.get_type ().name ())); + of.keyval(" toto" , "%s (string)" .printf(obj.type_object.toto)); + of.keyval(" tapa" , "%s (string)" .printf(obj.type_object.tata)); + of.keyval(" titi" , "%d (int)" .printf(obj.type_object.titi)); + of.keyval(" tutu" , "%s (bool)" .printf(obj.type_object.tutu.to_string ())); + obj.type_object.method_a (); + if (obj.type_gee_al != null) { + of.keyval("type_gee_al", "(%s)" .printf(obj.type_gee_al.get_type ().name ())); + foreach (string v in obj.type_gee_al) { + of.echo(" - item : %s".printf (v)); + } + } + + var n = Yaml.Builder.to_node (obj); + if ((done = n !=null)) { + n.display_childs (); + } + + of.rs (done); + of.echo (); + return (int) done; + +} diff --git a/src/vala/Pluie/Yaml.Builder.vala b/src/vala/Pluie/Yaml.Builder.vala index a00a8c0..f0eeef0 100644 --- a/src/vala/Pluie/Yaml.Builder.vala +++ b/src/vala/Pluie/Yaml.Builder.vala @@ -131,6 +131,7 @@ public class Pluie.Yaml.Builder Yaml.dbg_action ("vala type founded", "%s (%s)".printf (type.name (), type.to_string ())); if (type.is_object ()) { obj = (Yaml.Object) GLib.Object.new (type); + obj.set ("yaml_name", node.name); if (node!= null && !node.empty ()) { GLib.ParamSpec? def = null; Yaml.Node? scalar = null; @@ -174,7 +175,7 @@ public class Pluie.Yaml.Builder } else if (Yaml.Object.register.is_registered_type(parentType, type)) { Yaml.dbg ("%s is a registered type".printf (type.name ())); - obj.populate_by_type (type, node); + obj.populate_from_node (type, node); } else { Dbg.error ("%s is not registered and cannot be populated".printf (type.name ()), Log.METHOD, Log.LINE); @@ -238,6 +239,58 @@ public class Pluie.Yaml.Builder } } + /** + * + */ + public static string? get_basic_type_value (GLib.Object obj, GLib.Type type, string name) + { + GLib.Value v = GLib.Value(Type.STRING); + switch (type) + { + case Type.STRING : + string s; + obj.get (name, out s); + v = s; + break; + case Type.CHAR : + char c; + obj.get (name, out c); + v = c.to_string (); + break; + case Type.UCHAR : + uchar c; + obj.get (name, out c); + break; + case Type.UINT64 : + case Type.UINT : + uint64 i; + obj.get (name, out i); + break; + case Type.INT64 : + case Type.INT : + int64 i; + obj.get (name, out i); + v = i.to_string (); + break; + case Type.BOOLEAN : + bool b; + obj.get (name, out b); + v = b.to_string (); + break; + case Type.DOUBLE : + double d; + obj.get (name, out d); + v = "%f".printf (d); + break; + case Type.FLOAT : + float f; + obj.get (name, out f); + v = "%f".printf (f); + break; + } + return (string) v; + } + /** * */ @@ -259,4 +312,53 @@ public class Pluie.Yaml.Builder //~ of.echo ("enumValue : %d".printf (enumval.value)); } + public static string transform_param_name (string name) + { + return name.replace("-", "_"); + } + + /** + * + */ + public static Yaml.Node to_node (Yaml.Object obj, Yaml.Node? parent = null, bool root = true) + { + var node = new Yaml.Mapping (parent, obj.yaml_name); + string? name = null; + foreach (var def in obj.get_class ().list_properties ()){ + name = Yaml.Builder.transform_param_name(def.name); + if (name != null && name != "yaml_name") { + 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) { + node.add (child); + } + } + else if (def.value_type.is_enum ()) { + EnumValue enumval; + 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"); + + } + else if (def.value_type.is_fundamental ()) { + string data = Yaml.Builder.get_basic_type_value(obj, def.value_type, name); + if (data != null) { + new Yaml.Mapping.with_scalar (node, name, (string) data); + } + } + else { + of.error ("type %s for property %s is not registered".printf (def.value_type.name (), name)); + } + } + } + node.tag = new Yaml.Tag (obj.get_type ().name (), "v"); + if (root) { + var rootNode = new Yaml.Root(); + rootNode.add (node); + rootNode.tag_directives["!v!"] = "tag:pluie.org,2018:vala/"; + return rootNode; + } + else return node; + } } diff --git a/src/vala/Pluie/Yaml.Example.vala b/src/vala/Pluie/Yaml.Example.vala index 186b506..87121e3 100644 --- a/src/vala/Pluie/Yaml.Example.vala +++ b/src/vala/Pluie/Yaml.Example.vala @@ -78,13 +78,13 @@ public class Pluie.Yaml.Example : Yaml.Object protected override void yaml_init () { // base.yaml_init (); - Dbg.msg ("Yaml.Object %s (%s) instantiated".printf (this.myname, this.type_from_self ()), Log.LINE, Log.FILE); + Dbg.msg ("Yaml.Object %s (%s) instantiated".printf (this.myname, this.get_type().name ()), Log.LINE, Log.FILE); } /** * */ - public override void populate_by_type(GLib.Type type, Yaml.Node node) + public override void populate_from_node(GLib.Type type, Yaml.Node node) { try { if (type == typeof (Yaml.ExampleStruct)) { @@ -104,4 +104,27 @@ public class Pluie.Yaml.Example : Yaml.Object } } + /** + * + */ + public override Yaml.Node? populate_to_node(GLib.Type type, string name) + { + Yaml.Node? node = base.populate_to_node (type, name); + 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); + } + } + node.tag = new Yaml.Tag (type.name (), "v"); + } + return node; + } } diff --git a/src/vala/Pluie/Yaml.ExampleChild.vala b/src/vala/Pluie/Yaml.ExampleChild.vala index 4a8cffe..5bd41b1 100644 --- a/src/vala/Pluie/Yaml.ExampleChild.vala +++ b/src/vala/Pluie/Yaml.ExampleChild.vala @@ -40,6 +40,6 @@ public class Pluie.Yaml.ExampleChild : Yaml.Object public void method_a () { - of.echo (" called method from object %s builded via yaml".printf (this.type_from_self ())); + of.echo (" called method from object %s builded via yaml".printf (this.get_type().name ())); } } diff --git a/src/vala/Pluie/Yaml.ExampleStruct.vala b/src/vala/Pluie/Yaml.ExampleStruct.vala index d13289f..291bfd0 100644 --- a/src/vala/Pluie/Yaml.ExampleStruct.vala +++ b/src/vala/Pluie/Yaml.ExampleStruct.vala @@ -27,12 +27,27 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - +/** + * + */ public struct Pluie.Yaml.ExampleStruct { + /** + * + */ public uint red; + /** + * + */ public uint green; + /** + * + */ public uint blue; + + /** + * + */ public static ExampleStruct from_yaml_node (Yaml.Node node) { var s = ExampleStruct (); @@ -52,6 +67,10 @@ public struct Pluie.Yaml.ExampleStruct } return s; } + + /** + * + */ public string to_string () { return "%s(red:%u,green:%u,blue:%u)".printf ((typeof (ExampleStruct)).name (), this.red, this.green, this.blue); diff --git a/src/vala/Pluie/Yaml.Object.vala b/src/vala/Pluie/Yaml.Object.vala index a18cbac..6c23c71 100644 --- a/src/vala/Pluie/Yaml.Object.vala +++ b/src/vala/Pluie/Yaml.Object.vala @@ -38,7 +38,17 @@ public abstract class Pluie.Yaml.Object : GLib.Object /** * */ - public static Yaml.Register register { get; private set; } + public string yaml_name { get; internal set; } + + /** + * + */ + public static Yaml.Register register { get; private set; } + + /** + * + */ + public static Yaml.Tag yaml_tag { get; internal set; } /** * @@ -46,6 +56,7 @@ public abstract class Pluie.Yaml.Object : GLib.Object static construct { register = new Yaml.Register(); + yaml_tag = new Tag (typeof (Pluie.Yaml.Object).name (), "v"); } /** @@ -53,24 +64,30 @@ public abstract class Pluie.Yaml.Object : GLib.Object */ public virtual void yaml_init () { - Dbg.msg ("Yaml.Object (%s) instantiated".printf (this.type_from_self ()), Log.LINE, Log.FILE); - } - - /** - * retiew GLib.Type related to instance - */ - public string type_from_self () - { - return Type.from_instance (this).name (); + Dbg.msg ("Yaml.Object (%s) instantiated".printf (this.get_type().name ()), Log.LINE, Log.FILE); } /** * */ - public virtual void populate_by_type(GLib.Type type, Yaml.Node node) + public virtual void populate_from_node(GLib.Type type, Yaml.Node node) { if (type.is_a (typeof (Yaml.Object))) { this.set (node.name, Yaml.Builder.from_node(node, type)); } } + + /** + * + */ + public virtual Yaml.Node? populate_to_node(GLib.Type type, string name) + { + Yaml.Node? node = null; + if (type.is_a (typeof (Yaml.Object))) { + var o = (Yaml.Object) GLib.Object.new (type); + this.get (name, out o); + node = Yaml.Builder.to_node (o, null, false); + } + return node; + } } diff --git a/valadoc.sh b/valadoc.sh index 45c0669..c2c30c5 100755 --- a/valadoc.sh +++ b/valadoc.sh @@ -1,5 +1,4 @@ #!/bin/bash -#!/bin/bash # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @software : pluie-yaml