[][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 small::{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: &SmallRef) -> 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: &SmallRef) -> Result<Self, SmallError>

The from_small() function describes how to create a data-structure from the parts of SmallRef. See example 1 for canonical usage.

path(small: &SmallRef, key_path: &str) -> Result<Self, SmallError>

Reduces SmallRef 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 represents a string in Small data format.

SmallRef

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

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.