mirror of
https://github.com/mbierlee/mirage-config.git
synced 2024-11-14 20:34:00 +01:00
Support ini-like sections in keyvalue config
This commit is contained in:
parent
42e93e64d0
commit
089e42a2bf
|
@ -12,14 +12,15 @@
|
||||||
module mirage.java;
|
module mirage.java;
|
||||||
|
|
||||||
import mirage.config : ConfigDictionary;
|
import mirage.config : ConfigDictionary;
|
||||||
import mirage.keyvalue : KeyValueConfigFactory, SupportHashtagComments, SupportSemicolonComments;
|
import mirage.keyvalue : KeyValueConfigFactory, SupportHashtagComments, SupportSemicolonComments, SupportSections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates configuration files from Java properties.
|
* Creates configuration files from Java properties.
|
||||||
*/
|
*/
|
||||||
class JavaPropertiesFactory : KeyValueConfigFactory!(
|
class JavaPropertiesFactory : KeyValueConfigFactory!(
|
||||||
SupportHashtagComments.yes,
|
SupportHashtagComments.yes,
|
||||||
SupportSemicolonComments.no
|
SupportSemicolonComments.no,
|
||||||
|
SupportSections.no
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,15 @@ module mirage.keyvalue;
|
||||||
|
|
||||||
import mirage.config : ConfigFactory, ConfigDictionary, ConfigNode, ValueNode, ObjectNode, ConfigCreationException;
|
import mirage.config : ConfigFactory, ConfigDictionary, ConfigNode, ValueNode, ObjectNode, ConfigCreationException;
|
||||||
|
|
||||||
import std.string : lineSplitter, strip, startsWith, split, indexOf;
|
import std.string : lineSplitter, strip, startsWith, endsWith, split, indexOf;
|
||||||
import std.array : array;
|
import std.array : array;
|
||||||
import std.exception : enforce;
|
import std.exception : enforce;
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
import std.typecons : Flag;
|
import std.typecons : Flag;
|
||||||
|
|
||||||
alias SupportHashtagComments = Flag!"supportHashtagComment";
|
alias SupportHashtagComments = Flag!"SupportHashtagComments";
|
||||||
alias SupportSemicolonComments = Flag!"supportSemicolonComments";
|
alias SupportSemicolonComments = Flag!"SupportSemicolonComments";
|
||||||
|
alias SupportSections = Flag!"SupportSections";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic reusable key/value config factory that can be configured to parse
|
* A generic reusable key/value config factory that can be configured to parse
|
||||||
|
@ -28,7 +29,8 @@ alias SupportSemicolonComments = Flag!"supportSemicolonComments";
|
||||||
*/
|
*/
|
||||||
class KeyValueConfigFactory(
|
class KeyValueConfigFactory(
|
||||||
SupportHashtagComments supportHashtagComments = SupportHashtagComments.no,
|
SupportHashtagComments supportHashtagComments = SupportHashtagComments.no,
|
||||||
SupportSemicolonComments supportSemicolonComments = SupportSemicolonComments.no
|
SupportSemicolonComments supportSemicolonComments = SupportSemicolonComments.no,
|
||||||
|
SupportSections supportSections = SupportSections.no
|
||||||
) : ConfigFactory {
|
) : ConfigFactory {
|
||||||
/**
|
/**
|
||||||
* Parse a configuration file following the configured key/value conventions.
|
* Parse a configuration file following the configured key/value conventions.
|
||||||
|
@ -41,33 +43,41 @@ class KeyValueConfigFactory(
|
||||||
enforce!ConfigCreationException(contents !is null, "Contents cannot be null.");
|
enforce!ConfigCreationException(contents !is null, "Contents cannot be null.");
|
||||||
auto lines = contents.lineSplitter().array;
|
auto lines = contents.lineSplitter().array;
|
||||||
auto properties = new ConfigDictionary();
|
auto properties = new ConfigDictionary();
|
||||||
|
auto section = "";
|
||||||
foreach (size_t index, string line; lines) {
|
foreach (size_t index, string line; lines) {
|
||||||
auto normalizedLine = line;
|
auto processedLine = line;
|
||||||
|
|
||||||
if (supportHashtagComments) {
|
if (supportHashtagComments) {
|
||||||
auto commentPosition = normalizedLine.indexOf('#');
|
auto commentPosition = processedLine.indexOf('#');
|
||||||
if (commentPosition >= 0) {
|
if (commentPosition >= 0) {
|
||||||
normalizedLine = normalizedLine[0 .. commentPosition];
|
processedLine = processedLine[0 .. commentPosition];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supportSemicolonComments) {
|
if (supportSemicolonComments) {
|
||||||
auto commentPosition = normalizedLine.indexOf(';');
|
auto commentPosition = processedLine.indexOf(';');
|
||||||
if (commentPosition >= 0) {
|
if (commentPosition >= 0) {
|
||||||
normalizedLine = normalizedLine[0 .. commentPosition];
|
processedLine = processedLine[0 .. commentPosition];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
normalizedLine = normalizedLine.strip;
|
processedLine = processedLine.strip;
|
||||||
if (normalizedLine.length == 0) {
|
|
||||||
|
if (supportSections && processedLine.startsWith('[') && processedLine.endsWith(']')) {
|
||||||
|
section = processedLine[1 .. $ - 1] ~ '.';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parts = normalizedLine.split('=');
|
if (processedLine.length == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parts = processedLine.split('=');
|
||||||
enforce!ConfigCreationException(parts.length <= 2, "Line has too many equals signs and cannot be parsed (L" ~ index
|
enforce!ConfigCreationException(parts.length <= 2, "Line has too many equals signs and cannot be parsed (L" ~ index
|
||||||
.to!string ~ "): " ~ normalizedLine);
|
.to!string ~ "): " ~ processedLine);
|
||||||
enforce!ConfigCreationException(parts.length == 2, "Missing value assignment (L" ~ index.to!string ~ "): " ~ normalizedLine);
|
enforce!ConfigCreationException(parts.length == 2, "Missing value assignment (L" ~ index.to!string ~ "): " ~ processedLine);
|
||||||
properties.set(parts[0].strip, parts[1].strip);
|
|
||||||
|
properties.set(section ~ parts[0].strip, parts[1].strip);
|
||||||
}
|
}
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
|
@ -156,4 +166,29 @@ version (unittest) {
|
||||||
assert(config.get("server") == "localhost");
|
assert(config.get("server") == "localhost");
|
||||||
assert(config.get("port") == "9876");
|
assert(config.get("port") == "9876");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@("Support sections when enabled")
|
||||||
|
unittest {
|
||||||
|
auto config = new KeyValueConfigFactory!(SupportHashtagComments.no,
|
||||||
|
SupportSemicolonComments.yes,
|
||||||
|
SupportSections.yes)().parseConfig("
|
||||||
|
applicationName = test me!
|
||||||
|
|
||||||
|
[server]
|
||||||
|
host=localhost
|
||||||
|
port=2873
|
||||||
|
|
||||||
|
[server.middleware] ; Stuff that handles the http protocol
|
||||||
|
protocolServer = netty
|
||||||
|
|
||||||
|
[database.driver]
|
||||||
|
id=PostgresDriver
|
||||||
|
");
|
||||||
|
|
||||||
|
assert(config.get("applicationName") == "test me!");
|
||||||
|
assert(config.get("server.host") == "localhost");
|
||||||
|
assert(config.get("server.port") == "2873");
|
||||||
|
assert(config.get("server.middleware.protocolServer") == "netty");
|
||||||
|
assert(config.get("database.driver.id") == "PostgresDriver");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,5 +10,6 @@
|
||||||
module mirage;
|
module mirage;
|
||||||
|
|
||||||
public import mirage.config;
|
public import mirage.config;
|
||||||
|
public import mirage.java;
|
||||||
public import mirage.json;
|
public import mirage.json;
|
||||||
public import mirage.java;
|
public import mirage.keyvalue;
|
Loading…
Reference in a new issue