Expand description
A simple configuration language.
Nccl is an easy way to add minimal configuration to your crate without having to deal with complicated interfaces, obnoxious syntax, or outdated languages. Nccl makes it easy for a user to pick up your configuration. It’s as easy as five cents.
Nccl was motivated by the fact that other configuration languages are too complicated for both end-users and developers. Everyone loves types, but in a configuration language, there’s too much room for interpretation There are no types here.
This is a nice approach for smaller, non-semantic configurations; you shouldn’t be accidentally implementing a DSL with nccl, and if you are, it should feel painful.
For interacting with a parsed configuration, see config::Config
.
§Syntax
The single most important feature:
key
value
let source = r#"
key
value
"#;
let config = nccl::parse_config(&source).unwrap();
assert_eq!(config["key"].value(), Some("value"));
Results in config["key"].value() == Some("value")
. Note that there is no
semantic difference between a key and a value, so config.value() == Some("key")
.
For most of this document and the library source code, the words key, value, and
node are used almost interchangeably.
There are no types:
let source = r#"
threads
16
is this a problem?
no 🇳🇴
end of the world
2012-12-21"#;
let config = nccl::parse_config(&source).unwrap();
assert_eq!(config["is this a problem?"].value(), Some("no 🇳🇴"));
Interpret the data however you want.
Indentation is significant. Each top-level key-value pair must use the same type of indentation for each sub-value. You may mix indentation per-file.
let source = r#"
# tab
a
1
# single space
b
2
"#;
let config = nccl::parse_config(&source).unwrap();
assert_eq!(config["a"].value(), Some("1"));
assert_eq!(config["b"].value(), Some("2"));
Comments exist on their own line or after a quoted value, otherwise they become part of the value.
let source = r#"
hello # this is part of the key!
# this is not
world
"y'all" # this isn't either
"#;
let config = nccl::parse_config(&source).unwrap();
assert!(config.has_value("hello # this is part of the key!"));
assert!(!config["hello # this is part of the key!"].has_value("# this is not"));
assert!(config["hello # this is part of the key!"].has_value("y'all"));
Duplicate keys have their values merged.
let source = r#"
oh christmas tree
o tannenbaum
oh christmas tree
o tannenbaum
five golden rings
wait wrong song
"#;
let config = nccl::parse_config(&source).unwrap();
assert_eq!(
vec!["o tannenbaum", "five golden rings", "wait wrong song"],
config["oh christmas tree"].values().collect::<Vec<_>>()
);
Results in one key “oh christmas tree” with three values. This property
enables parse_config_with
to merge two configurations together. Say if
you wanted to enable an end user to be able to override some default values,
first you would parse the user’s configuration, and then parse the default
on top of that. config::Config::value
always returns the first value,
which would be the user’s value.
Values can have quotes if you want escape codes or multiple lines. Supported escape sequences are newlines, carriage returns, both quotes, and line breaks.
let source = r#"
# both single and double quotes work
i can
# with parse_quoted(), expands to the rust string "show\nyou"
'show\nyou'
# backslash followed by newline replaces all following whitespace
# except newlines with one space character. expands to "the world"
"the \
world"
# results in a single value for jingle = jangle
jingle
jangle
"jangle"
'jangle'
"#;
let config = nccl::parse_config(&source).unwrap();
assert_eq!(1, config["jingle"].values().count());
assert_eq!(
Ok(vec![String::from("show\nyou"), String::from("the world")]),
config["i can"]
.children()
.map(|value| value.parse_quoted())
.collect::<Result<Vec<_>, _>>()
);
Re-exports§
pub use config::Config;
Modules§
- Contains the configuration struct
- Module containing the parser
- Contains types relevant to scanning nccl sources
Enums§
- Errors that may occur while parsing
Functions§
- Parse a nccl configuration
- Parse a new nccl configuration on top of another