Add public inline documentation

This commit is contained in:
Mike Bierlee 2022-09-24 19:31:21 +03:00
parent 20a7c0471b
commit 32598ca434
2 changed files with 89 additions and 1 deletions

View file

@ -1,4 +1,6 @@
/** /**
* Base utilities for working with configurations.
*
* Authors: * Authors:
* Mike Bierlee, m.bierlee@lostmoment.com * Mike Bierlee, m.bierlee@lostmoment.com
* Copyright: 2022 Mike Bierlee * Copyright: 2022 Mike Bierlee
@ -14,18 +16,27 @@ import std.string : split, startsWith, endsWith, join, lastIndexOf;
import std.conv : to, ConvException; import std.conv : to, ConvException;
import std.file : readText; import std.file : readText;
/**
* Used by the ConfigDictionary when something goes wrong when reading configuration.
*/
class ConfigReadException : Exception { class ConfigReadException : Exception {
this(string msg, string file = __FILE__, size_t line = __LINE__) { this(string msg, string file = __FILE__, size_t line = __LINE__) {
super(msg, file, line); super(msg, file, line);
} }
} }
/**
* Used by ConfigFactory instances when loading or parsing configuration fails.
*/
class ConfigCreationException : Exception { class ConfigCreationException : Exception {
this(string msg, string file = __FILE__, size_t line = __LINE__) { this(string msg, string file = __FILE__, size_t line = __LINE__) {
super(msg, file, line); super(msg, file, line);
} }
} }
/**
* Used by ConfigDictionary when there is something wrong with the path when calling ConfigDictionary.get()
*/
class PathParseException : Exception { class PathParseException : Exception {
this(string msg, string path, string file = __FILE__, size_t line = __LINE__) { this(string msg, string path, string file = __FILE__, size_t line = __LINE__) {
string fullMsg = msg ~ " (Path: " ~ path ~ ")"; string fullMsg = msg ~ " (Path: " ~ path ~ ")";
@ -33,10 +44,17 @@ class PathParseException : Exception {
} }
} }
/**
* The configuration tree is made up of specific types of ConfigNodes.
* Used as generic type for ConfigFactory and ConfigDictionary.
*/
interface ConfigNode { interface ConfigNode {
string nodeType(); string nodeType();
} }
/**
* A configuration item that is any sort of primitive value (strings, numbers or null).
*/
class ValueNode : ConfigNode { class ValueNode : ConfigNode {
string value; string value;
@ -52,6 +70,11 @@ class ValueNode : ConfigNode {
} }
} }
/**
* A configuration item that is an object.
*
* ObjectNodes contain a node dictionary that points to other ConfigNodes.
*/
class ObjectNode : ConfigNode { class ObjectNode : ConfigNode {
ConfigNode[string] children; ConfigNode[string] children;
@ -73,6 +96,11 @@ class ObjectNode : ConfigNode {
} }
} }
/**
* A configuration item that is an array.
*
* Contains other ConfigNodes as children.
*/
class ArrayNode : ConfigNode { class ArrayNode : ConfigNode {
ConfigNode[] children; ConfigNode[] children;
@ -177,6 +205,9 @@ private class ConfigPath {
} }
} }
/**
* A ConfigDictionary contains the configuration tree and facilities to get values from that tree.
*/
class ConfigDictionary { class ConfigDictionary {
ConfigNode rootNode; ConfigNode rootNode;
@ -187,9 +218,21 @@ class ConfigDictionary {
this.rootNode = rootNode; this.rootNode = rootNode;
} }
/**
* Get values from the configuration using config path notation.
*
* Params:
* configPath = Path to the wanted config value. The path is separated by dots, e.g. "server.public.hostname".
* Values from arrays can be selected by brackets, for example: "server[3].hostname.ports[0]".
* When the config is just a value, for example just a string, it can be fetched by just specifying "." as path.
* Although the path should be universally the same over all types of config files, some might not lend to this structure,
* and have a more specific way of retrieving data from the config. See the examples and specific config factories for
* more details.
*
* Returns: The value at the path in the configuration. It is always a string so the user will have to convert it to other types.
*/
string get(string configPath) { string get(string configPath) {
enforce!ConfigReadException(rootNode !is null, "The config is empty"); enforce!ConfigReadException(rootNode !is null, "The config is empty");
// enforce!ConfigReadException(configPath.length > 0, "Supplied config path is empty");
auto path = new ConfigPath(configPath); auto path = new ConfigPath(configPath);
auto currentNode = rootNode; auto currentNode = rootNode;
@ -266,12 +309,29 @@ class ConfigDictionary {
} }
} }
/**
* The base class used by configuration factories for specific file types.
*/
abstract class ConfigFactory { abstract class ConfigFactory {
/**
* Loads a configuration from the specified path from disk.
*
* Params:
* path = Path to file. OS dependent, but UNIX paths are generally working.
* Returns: The parsed configuration.
*/
ConfigDictionary loadFile(string path) { ConfigDictionary loadFile(string path) {
auto json = readText(path); auto json = readText(path);
return parseConfig(json); return parseConfig(json);
} }
/**
* Parse configuration from the given string.
*
* Params:
* contents = Text contents of the config to be parsed.
* Returns: The parsed configuration.
*/
ConfigDictionary parseConfig(string contents); ConfigDictionary parseConfig(string contents);
} }

View file

@ -1,4 +1,6 @@
/** /**
* Utilities for loading JSON configurations.
*
* Authors: * Authors:
* Mike Bierlee, m.bierlee@lostmoment.com * Mike Bierlee, m.bierlee@lostmoment.com
* Copyright: 2022 Mike Bierlee * Copyright: 2022 Mike Bierlee
@ -14,15 +16,41 @@ import std.conv : to;
import mirage.config : ConfigFactory, ConfigDictionary, ConfigNode, ValueNode, ObjectNode, ArrayNode, ConfigCreationException; import mirage.config : ConfigFactory, ConfigDictionary, ConfigNode, ValueNode, ObjectNode, ArrayNode, ConfigCreationException;
/**
* Creates configuration dictionaries from JSONs.
*/
class JsonConfigFactory : ConfigFactory { class JsonConfigFactory : ConfigFactory {
/**
* Parse configuration from the given JSON string.
*
* Params:
* contents = Text contents of the config to be parsed.
* Returns: The parsed configuration.
*/
override ConfigDictionary parseConfig(string contents) { override ConfigDictionary parseConfig(string contents) {
return parseJson(parseJSON(contents)); return parseJson(parseJSON(contents));
} }
/**
* Parse configuration from a JSONValue tree.
*
* Params:
* contents = Text contents of the config to be parsed.
* Returns: The parsed configuration.
*/
ConfigDictionary parseJson(JSONValue json) { ConfigDictionary parseJson(JSONValue json) {
return new ConfigDictionary(convertJValue(json)); return new ConfigDictionary(convertJValue(json));
} }
/**
* Alias for parseConfig
*
* Params:
* contents = Text contents of the config to be parsed.
* Returns: The parsed configuration.
* See_Also: parseConfig
*/
ConfigDictionary parseJson(string json) { ConfigDictionary parseJson(string json) {
return parseConfig(json); return parseConfig(json);
} }