# 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()
---> --->
------------- ----------- ----------
------------- ----------- ----------
<--- <---
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"
```