sml 0.1.13

Simple markup language.
Documentation
# SML

`SML` is a simple markup language. It is designed to convert human readable information into
Rust data-structures.

The format looks this,

```text
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.

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.

4. Separation of lines has meaning.

5. Keys may not include `:`.

6. Double quotes in values must be escaped using `\"`.

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

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

## Basic Organization

```text
           ToSmall
           trait          to_string()
             --->           --->
-------------    -----------    ----------
| data-     |    |  Small  |    | String |
| structure |    |         |    |        |
-------------    -----------    ----------
             <---           <---
           FromSmall      from_str()
           trait
```

## Example


To convert from `Small` to a data-structure,

```rust
use small::{Small, FromSmall, SmallError};

#[derive(Debug)]
struct Hobbit {
    name:    String,
    age:     u32,
    friends: Vec<Hobbit>,
    bicycle: Option<String>,
}

impl Small for Hobbit {
    fn from_small(small: Small) -> Result<Self, SmallError> {
        Ok(Self {
            name:    String::sml(&small, "hobbit::name")?,
            age:     u32::sml(&small, "hobbit::age")?,
            friends: Vec::<Hobbit>::sml(&small, "hobbit::friends::hobbit")?,
            bicycle: Option::<String>::sml(&small, "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);
}

```

and to convert from a data-structure to `Small`,

```rust
use sml::{Small, ToSmall, SmallError};

#[derive(Debug)]
struct Hobbit {
    name:    String,
    age:     u32,
    friends: Vec<Hobbit>,
    bicycle: Option<String>,
}

impl ToSmall for Hobbit {
    fn to_small(&self, key: &str) -> Result<Small, SmallError> {
        Small::join(key, &vec!(
            self.name.to_small("name")?,                
            self.age.to_small("age")?,                     
            self.friends.to_small("friends")?,   
            self.bicycle.to_small("bicycle")?,
        ))
    }
}

println!("{}", frodo::to_small("hobbit"));

// hobbit:
//     name:         "Frodo Baggins"
//     age:          "98"
//     friends:
//         hobbit:
//             name: "Bilbo Baggins"
//             age:  "176"
//         hobbit:
//             name: "Samwise Gamgee"
//             age:  "66"
```