[][src]Crate sml

SML

SML is a simple markup language designed to convert human readable information into Rust types, focusing on simplicity, usability and hands-on control. Its optimal usage is in 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

  1. 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.

  2. All values must be double quoted.

  3. Every key/value combination must be nested in a key. For example

    hobbit: "Frodo"

by itself is invalid. It can be written:

    hobbit:
        name: "Frodo"

The motivation behind this is for the data format to distinguish clearly between whole data structures, which are headed by a key only, and parts of a data structure which are either key/value pairs, representing fields or variants, or other data-structures, which again are headed by a key only.

  1. Separation of lines has meaning.

  2. Keys must not include but must be followed by a colon :.

  3. Double quotes in values must be escaped using \".

  4. Everything after the second double quote is ignored (and can be used for commenting).

  5. Empty lines or lines with whitespace only are ignored.

Example. From Small-formatted string to your data-structure.

The following two examples should cover 90 percent of use cases. data-structure.

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(Self {
            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);
}

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. See example 1 for canonical usage.

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) -> Self

Top level function that converts a Small-formatted string into the receiver giving helpful error messages for debugging.

Structs

KeyPath
Small

Small is a selection of SmallString. Its function is to encapsulate path selections. See the path() function implemented by the FromSmall trait.

SmallString

SmallString represents a string in Small data format.

Token

The Token struct contains implementation details of a parsed line a Small-formatted string. It is not really part of the API, but gets passed around by SmallError and as such is public.

Enums

SmallError

Traits

FromSmall

Types that implement the FromSmall trait can be constructed from a Small-formatted string.