class Bindgen::ConfigReader::Parser
- Bindgen::ConfigReader::Parser
- YAML::Nodes::Parser
- YAML::Parser
- Reference
- Object
Overview
Pull parser for YAML configuration files, offering conditional branches and access to external dependencies.
If you want to read a configuration see ConfigReader.from_yaml.
This is done by hooking into the pull parser, manually checking for the conditional fields, and applying them accordingly.
Apart from this logic, the configuration file is still valid YAML.
Note: Conditionals and dependencies are only supported in
mappings (Hash in Crystal). Any such syntax encountered in something
other than a mapping will not trigger any special behaviour.
Condition syntax
YAML documents can define conditional parts in mappings by having a conditional key, with mapping value. If the condition matches, the mapping value will be transparently embedded. If it does not match, the value will be transparently skipped.
Condition keys look like if_X or elsif_X or else. X is the
condition, and it looks like Y_is_Z or Y_match_Z. You can also use
(one or more) spaces () instead of exactly one underscore (_) to
separate the words.
Y_is_Zis true if the variable Y equals Z case-sensitively.Y_isnt_Zis true if the variable Y doesn't equal Z case-sensitively.Y_match_Zis true if the variable Y is matched by the regular expression inZ. The regular expression is created case-sensitively.Y_newer_or_Zis true when variable Y is newer or equals (>=) to Z, variables are treated as versions.Y_older_or_Zis true when variable Y is older or equals (<=) to Z, variables are treated as versions.
A condition block is opened by the first if. Later condition keys can
use elsif or else (or if to open a new condition block).
Note: elsif or else without an if will raise an exception.
Their behaviour is like in Crystal: if starts a condition block, elsif
starts an alternative condition block, and else is used if none of if or
elsif matched. It's possible to mix condition key-values with normal
key-values.
Note: Conditions can be used in every mapping, even in mappings of a conditional. Each mapping acts as its own scope.
Variables
Variables are set by the user of the class (Probably through
ConfigReader.from_yaml). All variable values are strings.
Variable names are case-sensitive. A missing variable will be treated
as having an empty value ("").
Examples
foo: # A normal mapping
bar: 1
# A condition: Matches if `platform` equals "arm".
if_platform_is_arm: # In Crystal: `if platform == "arm"`
company: ARM et al
# You can mix in values between conditionals. It won't "break" following
# elsif or else blocks.
not_a_condition: Hello
# An elsif: Matches if 1) the previous conditions didn't match
# 2) its own condition matches.
elsif_platform_match_x86: # In Crystal: `elsif platform =~ /x86/`
company: Many different
# An else: Matches if all previous conditions didn't match.
else:
company: No idea
# At any time, you can start a new if sequence.
"if today is friday": # You can use spaces instead of underscores too
hooray: true
Dependencies
To modularize the configuration, you can require ("merge") external yaml files from within your configuration.
This is triggered by using a key named <<, and writing the file name as
value: <<: my_dependency.yml. The file-extension can also be omitted:
<<: my_dependency in which case an .yml extension is assumed.
The dependency path is relative to the currently processed YAML file.
You can also require multiple dependencies into the same mapping:
types:
Something: true # You can mix dependencies with normal fields.
<<: simple_types.yml
<<: complex_types.yml
<<: ignores.yml
The dependency will be embedded into the open mapping: It's transparent to the client code.
It's perfectly possible to mix conditionals with dependencies:
if_os_is_windows:
<<: windows-specific.yml
Errors
An exception will be raised if any of the following occur:
- The maximum dependency depth of
10(MAX_DEPTH) is exceeded. - The dependency name contains a dot:
../foo.ymlwon't work. - The dependency name is absolute:
/foo/bar.ymlwon't work.
Defined in:
bindgen/config_reader/parser.crConstant Summary
-
MAX_DEPTH =
10 -
Maximum dependency load depth.
Constructors
Class Method Summary
-
.loader : Loader
Default loader for dependencies.
-
.loader=(loader : Loader)
Default loader for dependencies.
Instance Method Summary
-
#depth : Int32
Parser depth, bounded by
MAX_DEPTH -
#evaluator : ConditionEvaluator
Evaluator for conditionals.
-
#loader : Loader
Instance local loader
-
#path : String
Path to the root YAML file.