mirror of
https://github.com/mbierlee/mirage-config.git
synced 2024-11-15 04:44:01 +01:00
Add JsonConfigFactory
This commit is contained in:
parent
1272ef1bc4
commit
fcbc372923
|
@ -19,6 +19,12 @@ class ConfigReadException : Exception {
|
|||
}
|
||||
}
|
||||
|
||||
class ConfigCreationException : Exception {
|
||||
this(string msg, string file = __FILE__, size_t line = __LINE__) {
|
||||
super(msg, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
class PathParseException : Exception {
|
||||
this(string msg, string path, string file = __FILE__, size_t line = __LINE__) {
|
||||
string fullMsg = msg ~ " (Path: " ~ path ~ ")";
|
||||
|
@ -26,11 +32,11 @@ class PathParseException : Exception {
|
|||
}
|
||||
}
|
||||
|
||||
private interface ConfigNode {
|
||||
interface ConfigNode {
|
||||
string nodeType();
|
||||
}
|
||||
|
||||
private class ValueNode : ConfigNode {
|
||||
class ValueNode : ConfigNode {
|
||||
string value;
|
||||
|
||||
this() {
|
||||
|
@ -45,7 +51,7 @@ private class ValueNode : ConfigNode {
|
|||
}
|
||||
}
|
||||
|
||||
private class ObjectNode : ConfigNode {
|
||||
class ObjectNode : ConfigNode {
|
||||
ConfigNode[string] children;
|
||||
|
||||
this() {
|
||||
|
@ -66,7 +72,7 @@ private class ObjectNode : ConfigNode {
|
|||
}
|
||||
}
|
||||
|
||||
private class ArrayNode : ConfigNode {
|
||||
class ArrayNode : ConfigNode {
|
||||
ConfigNode[] children;
|
||||
|
||||
this() {
|
||||
|
@ -158,7 +164,7 @@ private class ConfigPath {
|
|||
auto index = indexString.to!size_t;
|
||||
return ret(new ArrayPathSegment(index));
|
||||
} catch (ConvException e) {
|
||||
throw new PathParseException("Array index '" ~ indexString ~ "' is not acceptable as an array number", path);
|
||||
throw new PathParseException("Value '" ~ indexString ~ "' is not acceptable as an array index", path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,6 +179,13 @@ private class ConfigPath {
|
|||
class ConfigDictionary {
|
||||
ConfigNode rootNode;
|
||||
|
||||
this() {
|
||||
}
|
||||
|
||||
this(ConfigNode rootNode) {
|
||||
this.rootNode = rootNode;
|
||||
}
|
||||
|
||||
string get(string configPath) {
|
||||
enforce!ConfigReadException(rootNode !is null, "The config is empty");
|
||||
// enforce!ConfigReadException(configPath.length > 0, "Supplied config path is empty");
|
||||
|
@ -252,9 +265,9 @@ class ConfigDictionary {
|
|||
}
|
||||
}
|
||||
|
||||
interface ConfigLoader {
|
||||
ConfigDictionary parseConfig(string contents);
|
||||
interface ConfigFactory {
|
||||
ConfigDictionary loadFile(string path);
|
||||
ConfigDictionary parseConfig(string contents);
|
||||
}
|
||||
|
||||
version (unittest) {
|
||||
|
|
111
source/mirage/json.d
Normal file
111
source/mirage/json.d
Normal file
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* Authors:
|
||||
* Mike Bierlee, m.bierlee@lostmoment.com
|
||||
* Copyright: 2022 Mike Bierlee
|
||||
* License:
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* The full terms of the license can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
module mirage.json;
|
||||
|
||||
import std.json : JSONValue, JSONType;
|
||||
import std.conv : to;
|
||||
|
||||
import mirage.config : ConfigFactory, ConfigDictionary, ConfigNode, ValueNode, ObjectNode, ArrayNode, ConfigCreationException;
|
||||
|
||||
class JsonConfigFactory : ConfigFactory {
|
||||
ConfigDictionary loadFile(string path) {
|
||||
throw new Exception("not yet implemented");
|
||||
}
|
||||
|
||||
ConfigDictionary parseConfig(string contents) {
|
||||
throw new Exception("not yet implemented");
|
||||
}
|
||||
|
||||
ConfigDictionary parseJson(JSONValue json) {
|
||||
return new ConfigDictionary(convertJValue(json));
|
||||
}
|
||||
|
||||
ConfigDictionary parseJson(string json) {
|
||||
return parseConfig(json);
|
||||
}
|
||||
|
||||
private ConfigNode convertJValue(JSONValue json) {
|
||||
if (json.type() == JSONType.object) {
|
||||
auto objectNode = new ObjectNode();
|
||||
auto objectJson = json.object();
|
||||
foreach (propertyName, jvalue; objectJson) {
|
||||
objectNode.children[propertyName] = convertJValue(jvalue);
|
||||
}
|
||||
|
||||
return objectNode;
|
||||
}
|
||||
|
||||
if (json.type() == JSONType.array) {
|
||||
auto arrayNode = new ArrayNode();
|
||||
auto arrayJson = json.array();
|
||||
foreach (jvalue; arrayJson) {
|
||||
arrayNode.children ~= convertJValue(jvalue);
|
||||
}
|
||||
|
||||
return arrayNode;
|
||||
}
|
||||
|
||||
if (json.type() == JSONType.null_) {
|
||||
return new ValueNode(null);
|
||||
}
|
||||
|
||||
if (json.type() == JSONType.string) {
|
||||
return new ValueNode(json.get!string);
|
||||
}
|
||||
|
||||
if (json.type() == JSONType.integer) {
|
||||
return new ValueNode(json.integer.to!string);
|
||||
}
|
||||
|
||||
if (json.type() == JSONType.float_) {
|
||||
return new ValueNode(json.floating.to!string);
|
||||
}
|
||||
|
||||
throw new ConfigCreationException("JSONValue is not supported: " ~ json.toString());
|
||||
}
|
||||
}
|
||||
|
||||
version (unittest) {
|
||||
@("Parse JSON") unittest {
|
||||
JSONValue serverJson = ["hostname": "hosty.com", "port": "1234"];
|
||||
JSONValue nullJson = ["isNull": null];
|
||||
JSONValue socketsJson = [
|
||||
"/var/sock/one", "/var/sock/two", "/var/sock/three"
|
||||
];
|
||||
JSONValue numbersJson = [1, 2, 3, 4, -7];
|
||||
JSONValue decimalsJson = [1.2, 4.5, 6.7];
|
||||
JSONValue jsonConfig = [
|
||||
"server": serverJson, "sockets": socketsJson, "nully": nullJson,
|
||||
"numberos": numbersJson, "decimalas": decimalsJson
|
||||
];
|
||||
|
||||
auto loader = new JsonConfigFactory();
|
||||
auto config = loader.parseJson(jsonConfig);
|
||||
|
||||
assert(config.get("server.hostname") == "hosty.com");
|
||||
assert(config.get("server.port") == "1234");
|
||||
assert(config.get("sockets[2]") == "/var/sock/three");
|
||||
assert(config.get("nully.isNull") == null);
|
||||
assert(config.get("numberos[3]") == "4");
|
||||
assert(config.get("numberos[4]") == "-7");
|
||||
assert(config.get("decimalas[0]") == "1.2");
|
||||
assert(config.get("decimalas[2]") == "6.7");
|
||||
}
|
||||
|
||||
@("Parse JSON root values") unittest {
|
||||
auto loader = new JsonConfigFactory();
|
||||
|
||||
assert(loader.parseJson(JSONValue("hi")).get(".") == "hi");
|
||||
assert(loader.parseJson(JSONValue(1)).get(".") == "1");
|
||||
assert(loader.parseJson(JSONValue(null)).get(".") == null);
|
||||
assert(loader.parseJson(JSONValue(1.8)).get(".") == "1.8");
|
||||
assert(loader.parseJson(JSONValue([1, 2, 3])).get("[2]") == "3");
|
||||
}
|
||||
}
|
|
@ -10,3 +10,4 @@
|
|||
module mirage;
|
||||
|
||||
public import mirage.config;
|
||||
public import mirage.json;
|
||||
|
|
Loading…
Reference in a new issue