1 /**
2  * YAML Loader
3  *
4  * Copyright: (c) 2015-2016, Milofon Project.
5  * License: Subject to the terms of the BSD license, as written in the included LICENSE.txt file.
6  * Authors: Maksim Galanin
7  */
8 module proped.loaders.yaml;
9 
10 version(Have_dyaml):
11 
12 private
13 {
14     import dyaml.loader : Loader;
15     import dyaml.node : Node;
16     import dyaml.exception : YAMLException;
17 
18     import proped.properties : Properties, PropNode;
19     import proped.loader : PropertiesLoader;
20     import proped.exception : PropertiesException;
21 }
22 
23 
24 
25 /**
26  * The loader data from a YAML file
27  *
28  * Implements PropertiesLoader
29  */
30 class YAMLPropertiesLoader : PropertiesLoader
31 {
32     /**
33      * Loading properties from a file
34      *
35      * Params:
36      *
37      * fileName = Path to the file system
38      */
39     Properties loadPropertiesFile(string fileName)
40     {
41         Node root;
42 
43         try 
44             root = Loader(fileName).load();
45         catch(YAMLException e)
46             throw new PropertiesException("Error loading properties from a file '" ~ fileName ~ "':", e);
47 
48         return toProperties(root);
49     }
50 
51 
52     /**
53      * Loading properties from a string
54      *
55      * Params:
56      *
57      * data = Source string
58      */
59     Properties loadPropertiesString(string data)
60     {
61         Node root;
62 
63         try
64             root = Loader((cast(ubyte[])data).dup).load();
65         catch(YAMLException e)
66             throw new PropertiesException("Error loading properties from a string:", e);
67 
68         return toProperties(root);
69     }
70 
71 
72     private Properties toProperties(Node root)
73     {
74         PropNode convert(Node node)
75         {
76             if (!node.isValid)
77                 return PropNode();
78             else if (node.isInt)
79                 return PropNode(node.get!long);
80             else if (node.isFloat)
81                 return PropNode(node.get!double);
82             else if (node.isString)
83                 return PropNode(node.get!string);
84             else if (node.isBool)
85                 return PropNode(node.get!bool);
86             else if (node.isMapping)
87             {
88                 PropNode[string] map;
89                 foreach(string key, Node value; node)
90                     map[key] = convert(value);
91 
92                 return PropNode(map);
93             }
94             else if (node.isSequence)
95             {
96                 PropNode[] arr;
97                 foreach(Node value; node)
98                     arr ~= convert(value);
99 
100                 return PropNode(arr);
101             }
102             else
103                 return PropNode();
104         }
105 
106         return Properties(convert(root));
107     }
108 
109 
110     /**
111      * Returns the file extension to delermite the type loader
112      */
113     string[] getExtensions()
114     {
115         return [".yaml", ".yml"];
116     }
117 }
118