[−][src]Crate sml
SML
SML
is a simple markup language. It is designed to convert human readable information into
Rust data-structures. The focus is on simplicity, usability and hands-on control (no magic).
The format looks this,
hobbit:
name: "Frodo Baggins"
age: "98"
friends:
hobbit:
name: "Bilbo Baggins"
age: "176"
hobbit:
name: "Samwise Gamgee"
age: "66"
State of Progress
Small
was created for processing schemas and loading config files, where its better to
manually specify conversion types. This becomes overly verbose when used for serializing and
deserializing struct
s and enum
s, where data-structures tend to be nested within each other.
The goal is to reduce this verbosity by using procedural macros, but no deadlines are set for
this.
Data Format Rules
-
Indentation has meaning and is 4 spaces, relative to the top key.
-
All values must be double quoted.
-
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.
-
Separation of lines has meaning.
-
Keys may not include
:
. -
Double quotes in values must be escaped using
\"
. -
Everything after the second double quote is ignored (and can be used for commenting).
-
Empty lines or lines with whitespace only are ignored.
Basic Organization
--------------------------from_str()----------------------------
| |
| --------path()-------- |
| | | |
| | FromSmall trait | |
| | --from_small()-- | -----to_ref()---- --from_str()--- |
| | | | | | | | | |
v v v | | v | v | |
---------- ------------ --------- ----------
| Hobbit | | SmallRef |-ref into->| Small | | String |
---------- ------------ --------- ----------
^ ^ | ^
| | | |
------------ to_small()----------------- --to_string()--
ToSmall trait
Example 1: 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); }
Most standard-library types are implemented for FromSmall
. To custom convert strings from
Small
values to your data-type, use from_val(s: &SmallRef, key_path: &str)
which returns a
Vec
of String
s or from_unique_val(s: &SmallRef, key_path: &str)
which provides a single
String
value. These can then be used in the FromSmall
implementation for your
data-structure.
Example 2: From your data-structure to a Small-formatted string.
To convert from a data-structure to a string,
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("hobbit", &vec!( self.name.to_small("name")?, self.age.to_small("age")?, self.friends.to_small("friends")?, self.bicycle.to_small("bicycle")?, )) } } println!("{}", frodo::key("hobbit")); // hobbit: // name: "Frodo Baggins" // age: "98" // friends: // hobbit: // name: "Bilbo Baggins" // age: "176" // hobbit: // name: "Samwise Gamgee" // age: "66"
Functions on Small
join(key: &str, subs: &Vec<Small>) -> Result<Small, SmallError>
Returns a Small
type given a key and a Vec
of Small
s. The Vec
of Small
s are
indented below the key. See example 2.
key_value(key: &str, value: String) -> Result<Small, SmallError>
Returns a Small
type that consists of one key-value pair.
to_ref(&self) -> SmallRef
Converts self
into a SmallRef
.
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.
ToSmall
Trait
The ToSmall
trait is implemented for String
s, Vec<T>
, Option<T>
, bool
and all the
standard library integer and float types.
Required function:
fn to_small(&self, key: &str) -> Result<Small, SmallError>;
Converts a receiver that implements ToSmall
into a Small
-formatted string. key
can be
overridden in the implementation, depending on whether you want to data-structure itself to
set the key name or whether you want to context of the Small
-formatted string to set the
key name.
Structs
Small |
|
SmallRef |
|
Token | The |
Enums
SmallError |
Traits
FromSmall | Types that implement the |
ToSmall | Types that implement the ToSmall trait can be converted to the |