Crate libconfig [−] [src]
A library to parse and load configuration files.
This library parses and loads configuration files in much the same way as C/C++'s libconfig. At this time, it can only read and load configurations, but future plans include a much richer user API to allow other forms of interaction, such as manipulating values, writing the current configuration to a file, etc.
Getting started
A configuration file consists of a group of settings. A setting is a key/value pair, where the
key is a string of the form [a-zA-Z][-a-zA-Z0-9_]*
, and the value is anything represented by
types::Value
. In a configuration file, setting/value pairs are written as
setting_name = value;
. Possible values include primitive integer and floating point types,
strings, arrays, lists, etc.
The library provides a bunch of methods to read the configuration data in the reader
module.
The possibilities include reading from a string, from a file, or from anything that implements
the Read
trait.
As of now, every reader will first attempt to read the whole configuration into memory, and only begins parsing once everything was read.
In case of error, the parser returns a config::error
.
On success, the parser returns a Config
, which can then be used to browse the loaded data.
Browsing is typically done with the lookup_*
methods implemented by Config
. The lookup
methods work with paths. Essentially, a path unambiguously describes the location of
a setting.
For example, consider this input configuration file:
title = "My HTTP server"; listen_ports = [ 80, 443 ]; misc = { owner = "Chuck Norris"; location = "CA"; contact = { phone = "415-256-9999"; // This is an array. Arrays start with `[` and end with `]` // Arrays are homogeneous and can only hold scalar data types. // See types::ScalarValue for further information emails = ["chuck@norris.com", "chuck.norris@gmail.com"]; }; };
At the top level, we have 3 settings: title
, listen_ports
and misc
. misc
is itself a
group of settings. Each value in this configuration is reachable by a unique path of settings
to follow. Each setting in a path is separated by .
Example: The path misc.contact.phone
identifies the setting with value 415-256-9999
.
Array and list types are indexed using [i]
in a path.
Example: The path listen_ports.[1]
identifies the setting with value 443
.
Example: The path misc.contact.emails.[0]
identifies the setting with value
chuck@norris.com
Lists, as opposed to arrays, are heterogeneous and can store any data type, including other lists. Here's a setting consisting of a heterogeneous list:
// This is a list. Lists start with `(` and end with `)` // Lists are heterogeneous and can store any data type, including other lists a_setting = ("a string", // The first element is a string ((1, 2, 3)), // The 2nd element is a list storing a list of 3 integers misc = { x = 4; y = 3; } // 3rd element: a group );
Here are some valid paths for this example:
a_setting.[0]
- returns the string a string
a_setting.[1].[0].[2]
- returns the integer 3
a_setting.[2].misc.x
- returns the integer 4
Adjacent string literals separated by whitespace, newlines and / or comments are automatically concatenated.
Example:
"a"/* a comment */" string" " liter" // This is a commment "al"
is equivalent to:
"a string literal"
See the integration tests (in the tests/
directory) for sample use cases and more complex
examples.
Environment variables
The crate has an ability to inject environment variables into the configuration file. That becomes possible using special syntax:
$"SOME_ENV_VAR_NAME"::str
to inject the environment variablesSOME_ENV_VAR_NAME
as the string value. No additiocal changes are made ot the value.$"SOME_ENV_VAR_NAME"::bool
to inject the environment variableSOME_ENV_VAR_NAME
as the boolean value. The valuetrue
oryes
oron
or1
are converted intotrue
otherwise intofalse
.$"SOME_ENV_VAR_NAME"::int
to inject the environment variableSOME_ENV_VAR_NAME
as the integer value. The successfully parsed value is injected asi32
ori64
, depending on the format, otherwise0i32
is injected.$"SOME_ENV_VAR_NAME"::flt
to inject the environment variableSOME_ENV_VAR_NAME
as the floating value. The successfully parsed value is injected asf32
orf64
, depending on the format, otherwise0f32
is injected.$"SOME_ENV_VAR_NAME"::auto
or$"SOME_ENV_VAR_NAME"
to inject the environment variableSOME_ENV_VAR_NAME
and resolve the type automatically. Rules of the type auto-resolution:
- If the value is True or Yes or On then the result type is
boolean True
; - If the value is False or No or Off then the result type is
boolean False
; - If the value is floating then the result type is
floating
; - If the value is integer then the result type is
integer
; - Otherwise the result is
string
value.
- If the value is True or Yes or On then the result type is
Example:
#!/bin/sh export LOG_LEVEL=debug
// Configuration file log = { // Inject (use) the value of the environment variable LOG_LEVEL level = $"LOG_LEVEL"::str; }
Grammar
This section describes the configuration input format. The starting rule is conf
.
conf -> __ settings_list __
settings_list -> // empty
| setting settings_list
setting -> __ name __ (":"|"=") __ value __ ";" __
name -> [a-zA-Z][-a-zA-Z0-9_]*
value -> scalar_value
| array_value
| list_value
| group_value
scalar_value -> boolean_scalar_value
| floating64_scalar_value
| floating32_scalar_value
| integer64_scalar_value
| integer32_scalar_value
| str_scalar_value
| auto_env_scalar_value
boolean_scalar_value -> [Tt][Rr][Uu][Ee]
| [Yy][Ee][Ss]
| [Oo][Nn]
| [Ff][Aa][Ll][Ss][Ee]
| [Nn][Oo]
| [Oo][Ff][Ff]
| $"ENV_VAR_NAME"::bool
floating64_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?"L"
| $"ENV_VAR_NAME"::flt
floating32_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?
| $"ENV_VAR_NAME"::flt
integer32_scalar_value -> [+-]?[0-9]+
| $"ENV_VAR_NAME"::int
integer64_scalar_value -> [+-]?[0-9]+"L"
| $"ENV_VAR_NAME"::int
str_scalar_value -> __ str_literal __
| __ str_literal __ str_scalar_value
| $"ENV_VAR_NAME"::str
auto_env_scalar_value -> $"ENV_VAR_NAME"::auto
| $"ENV_VAR_NAME"
str_literal -> "\"" ([^\"\\]|(("\\r"|"\\n"|"\\t"|"\\\""|"\\\\")))* "\""
array_value -> "["
(bool_array |
flt64_array | flt32_array |
int64_array | int32_array |
str_array)
"]"
| "[" __ "]"
bool_array -> __ boolean_scalar_value __
| __ boolean_scalar_value __ "," __ bool_array
flt64_array -> __ floating64_scalar_value __
| __ floating64_scalar_value __ "," __ flt64_array
flt32_array -> __ floating32_scalar_value __
| __ floating32_scalar_value __ "," __ flt32_array
int64_array -> __ integer64_scalar_value __
| __ integer64_scalar_value __ "," __ int64_array
int32_array -> __ integer32_scalar_value __
| __ integer32_scalar_value __ "," __ int32_array
str_array -> __ str_scalar_value __
| __ str_scalar_value __ "," __ str_array
list_value -> "(" __ ")"
| "(" list_elements ")"
list_elements -> __ value __
| __ value __ "," __ list_elements
group_value -> "{" settings_list "}"
__ -> // empty
| whitespace __
| eol __
| comment __
whitespace -> [\s\t]
eol -> "\r\n"
| "\n"
comment -> single_line_comment
| multi_line_comment
single_line_comment -> ("//"|"#")[^\n]*"\n"?
multi_line_comment -> "/*"([^*]|"*"[^/])*"*/"
Modules
error |
Errors that can occur while parsing a configuration |
reader |
Reader types to parse a configuration. |
types |
Internal types used to represent a configuration and corresponding primitives to browse it |