1 /**
2  * Модуль содержит методы для работы со совйствами приложения
3  *
4  * Copyright: (c) 2015-2020, Milofon Project.
5  * License: Subject to the terms of the BSD 3-Clause License, as written in the included LICENSE.md file.
6  * Author: <m.galanin@milofon.pro> Maksim Galanin
7  * Date: 2020-04-11
8  */
9 
10 module dango.system.properties;
11 
12 private
13 {
14     import std.typecons : Nullable;
15 
16     import uniconf.core : UniConf, UniConfException;
17 }
18 
19 
20 /**
21  * Извление конфигурации
22  *
23  * Params:
24  * config = Объект содержащий необходимы ключ конфигурации
25  * msg = Сообщение об ошибке
26  *
27  * Returns: name
28  */
29 T getOrEnforce(T)(UniConf config, string key, string msg) @safe
30 {
31     auto val = config.opt!T(key);
32     if (val.isNull)
33         throw new UniConfException(msg);
34     return val.get;
35 }
36 
37 @("Should work getOrEnforce method with key")
38 @safe unittest
39 {
40     import std.exception : assertThrown;
41     auto conf = UniConf(["__name": UniConf("method")]);
42     assert (conf.getOrEnforce!string("__name", "not found") == "method");
43     conf = UniConf(1);
44     assertThrown!UniConfException(conf.getOrEnforce!int("name", "not found"));
45 }
46 
47 
48 /**
49  * Извление конфигурации
50  *
51  * Params:
52  * config = Объект содержащий необходимы ключ конфигурации
53  * msg = Сообщение об ошибке
54  *
55  * Returns: name
56  */
57 T getOrEnforce(T)(UniConf config, string msg) @safe
58 {
59     auto val = config.opt!T();
60     if (val.isNull)
61         throw new UniConfException(msg);
62     return val.get;
63 }
64 
65 @("Should work getOrEnforce method")
66 @safe unittest
67 {
68     import std.exception : assertThrown;
69     auto conf = UniConf("method");
70     assert (conf.getOrEnforce!string("not found") == "method");
71     conf = UniConf(1);
72     assertThrown!UniConfException(conf.getOrEnforce!string("not found"));
73 }
74 
75 
76 /**
77  * Извление имени из объекта конфигурации
78  *
79  * Params:
80  * config = Объект содержащий необходимы ключ конфигурации
81  * msg = Сообщение об ошибке
82  *
83  * Returns: name
84  */
85 string getNameOrEnforce(UniConf config, string msg) @safe
86 {
87     if (config.canMapping)
88         return config.getOrEnforce!string("__name", msg);
89     else
90     {
91         auto val = config.opt!string;
92         if (val.isNull)
93             throw new UniConfException(msg);
94         return val.get;
95     }
96 }
97 
98 @("Should work getNameOrEnforce method")
99 @safe unittest
100 {
101     import std.exception : assertThrown;
102     UniConf conf = UniConf("method"); 
103     assert (conf.getNameOrEnforce("not found") == "method");
104     conf = UniConf(["__name": UniConf("method")]);
105     assert (conf.getNameOrEnforce("not found") == "method");
106     conf = UniConf(1);
107     assertThrown!UniConfException(conf.getNameOrEnforce("not found"));
108 }
109 
110 
111 /**
112  * Преобразует UniConf в массив
113  * 
114  * Params:
115  * config = Объект конфигурации
116  */
117 UniConf[] toSequence(UniConf config) @safe
118 {
119     if (config.canSequence)
120         return config.getSequence();
121     else
122         return [config];
123 }
124 
125 @("Should work toSequence method")
126 @safe unittest
127 {
128     UniConf conf = UniConf(1); 
129     assert (conf.toSequence == [UniConf(1)]); 
130     conf = UniConf([UniConf(1), UniConf(2)]);
131     assert (conf.toSequence == [UniConf(1), UniConf(2)]); 
132 }
133 
134 
135 /**
136  * Преобразует UniConf в массив
137  * 
138  * Params:
139  * config = Объект конфигурации
140  */
141 UniConf[] toSequence(UniConf config, string key) @safe
142 {
143     auto val = config.opt!UniConf(key);
144     if (val.isNull)
145         return [];
146     return val.get.toSequence();
147 }
148 
149 @("Should work toSequence method with key")
150 @safe unittest
151 {
152     UniConf conf = UniConf(["one": UniConf(1)]);
153     assert (conf.toSequence("one") == [UniConf(1)]);
154     conf = UniConf(["one": UniConf([UniConf(1), UniConf(2)])]);
155     assert (conf.toSequence("one") == [UniConf(1), UniConf(2)]);
156 }
157 
158 
159 /**
160  * Возвращает зачение из Nullable или альтернативное значение
161  */
162 R getOrElse(R)(Nullable!R value, R alt) @safe nothrow
163 {
164     if (value.isNull)
165         return alt;
166     return value.get;
167 }
168 
169 @("Should work getOrElse method")
170 @safe unittest
171 {
172     UniConf conf = UniConf(["one": UniConf(1)]);
173     auto val = conf.opt!int("one");
174     assert (!val.isNull);
175     assert (val.getOrElse(2) == 1);
176     assert (conf.opt!int("two").getOrElse(2) == 2);
177 }
178