Expand description
§SML
SML is a simple markup language designed to convert human readable information into Rust
types with a very specific purpose of loading config files and schemas.
The format looks like
hobbit:
name: Frodo Baggins
age: 98
friends:
hobbit:
name: Bilbo Baggins
age: 176
hobbit:
name: Samwise Gamgee
age: 66§Data Format Rules
-
Indentation has meaning and is 4 spaces, relative to the top key. If indenting is relative to the top key, then you can neatly align strings embedded in code.
-
All values must be double quoted.
-
Key/value combinations are used for fields
name: "Frodo"are used for struct fields and enum variants. Keys only
hobbit:
name: "Frodo"indicate a complete struct or enum. In this way, the data clearly indicates the mapping to
Rust data structures.
-
Separation of lines has meaning.
-
Keys must not include but must be followed by a colon
:. -
Double quotes in values must be escaped using
\". -
Everything after the second double quote is ignored.
-
Empty lines or lines with whitespace only are ignored.
-
Comments require
//at the start of the line for example
// comment
hobbit:
name: "Frodo"§Example. From Small-formatted string to your data-structure.
This examples should cover 90 percent of use cases.
use sml::{Small, FromSmall, SmallError};
#[derive(Debug)]
struct Hobbit {
name: String,
age: u32,
friends: Vec<Hobbit>,
bicycle: Option<String>,
}
impl FromSmall for Hobbit {
fn from_small(s: &Small) -> Result<Self, SmallError> {
Ok(Hobbit {
name: String::path(&s, "hobbit::name")?,
age: u32::path(&s, "hobbit::age")?,
friends: Vec::<Hobbit>::path(&s, "hobbit::friends::hobbit")?,
bicycle: Option::<String>::path(&s, "hobbit::bicycle")?,
})
}
}
fn main() {
let s = r#"
hobbit:
name: "Frodo Baggins"
age: "98"
friends:
hobbit:
name: "Bilbo Baggins"
age: "176"
hobbit:
name: "Samwise Gamgee"
age: "66""#;
let frodo = Hobbit::from_str_debug(s);
println!("name: {}", frodo.name);
}§FromSmall Trait
Types that implement the FromSmall trait can be constructed from a Small-formatted string.
Required function:
from_small(slice: &Small) -> Result<Self, SmallError>The from_small() function describes how to create a data-structure from the parts of
Small.
path(small: &Small, key_path: &str) -> Result<Self, SmallError>Reduces Small to the key_path and then uses the FromSmall trait to convert to the
receiver type.
from_str(s: &str) -> Result<Self, SmallError>Top level function that convert a Small-formatted string into the receiver.
from_str_debug(s: &str) -> SelfTop level function that converts a Small-formatted string into the receiver giving helpful
error messages for debugging.
§Implementation
A Small value may be a collection of Small values. For example,
hobbit:
name: "Bilbo Baggins"
age: "176"
hobbit:
name: "Samwise Gamgee"
age: "66"is a collection of two elements
hobbit:
name: "Bilbo Baggins"
age: "176"and
hobbit:
name: "Samwise Gamgee"
age: "66"Often when implementing FromSmall we want to convert a Small object into a single value, so
we need to check that Small has only one element The implementation to convert from Small
to u32 gives indicates how to do this. unique_value() checks that there is only one element
in Small and if so returns that one element and value() extracts that value as a String.
impl FromSmall for u32 {
fn from_small(s: &Small) -> Result<Self, SmallError> {
let token = s.unique_value()?;
token
.value()?
.parse::<u32>()
.map_err(|_| SmallError::ParseValue(token, "u32"))
}
}Structs§
- KeyPath
- Small
Smallis a selection ofSmallString. Its function is to encapsulate path selections. See thepath()function implemented by theFromSmalltrait.- Small
String SmallStringrepresents a string inSmalldata format.- Token
- The
Tokenstruct contains implementation details of a parsed line aSmall-formatted string. It is not really part of the API, but gets passed around bySmallErrorand as such is public.
Enums§
Traits§
- From
Small - Types that implement the
FromSmalltrait can be constructed from aSmall-formatted string.