Variable

<variable> assigns a <value> to a <key>, in the form of

- <key>: <value>

Note that a space is required after the dash and colon.

Key

<key> can't be empty. It may contain any upper and lowercase letters (A-Za-z), digits (0-9), spaces (U+0020), and underscores (_), but can't start with a digit. Key names are case sensitive.

Some examples for valid key names are:

# Example
- key: value
- KEY: value
- key_1: value
- key_with_underscore: value
- _: value
(compile output)
TIP

Don't worry about what # Example is. For now just see this as the title for your REAM file, and all REAM files starts with a title. We'll discuss what it is in detail in Entry section.

Key name can't be empty:

# BadExample
- : value
(compile output)

Key name can't start with a digit:

# BadExample
- 1key: value
(compile output)
NOTE

This rule is not yet enforced.

DETAIL

Key names should support UTF-8, but ream-core does not support UTF-8 identifiers yet. It is recommended that you use only ASCII for now.

Value

String

# Example
- string: value
- long_string: Hello World
- quoted_string: "quote"
(compile output)

There is not need to quote strings. Quotation marks will be preserved.

Values can't contain line breaks. The following will raise an error:

# BadExample
- key_1: first line
         second line
- key_2: value
(compile output)

Note that REAM stores strings as raw literals, so the following example is valid. \n will not be escaped, and is equivalent to \\n in JSON.

# Example
- key_1: first line\nsecond line
- key_2: value
(compile output)

Number

Example:

# Example
- number_1: 1
- number_2: -2
- number_3: 3.1415926
(compile output)
DETAIL

REAM should probably distinguish between Integer and Float. In ream-core Numbers are validated through parsing as Rust's f64 type, but this may change in the future.

I might also introduce Fraction type.

Boolean

Boolean values are TRUE and FALSE, both uppercase.

Example:

# Example
- bool_1: TRUE
- bool_2: FALSE
- not_bool_1: true
- not_bool_2: False

Note that boolean values must be exact matches. Values that doesn't match the pattern are stored as strings.

(compile output)

Missing Value*

See DETAIL.

DETAIL

How should REAM represent missing value?

One solution is to simply add a None type.

Another solution is converting all REAM types into options. In Rust I would have to do something like type ReamString = Option<String>. That being said, all missing values require explicit type annotations since None is not a value type but a variant of an enumeration.

The benefit of such design is more obvious when references and filters are implemented. When referencing existing data for manipulation, users should think about how to deal with potential None values since referencing a Boolean returns Boolean::Some(TRUE), Boolean::Some(FALSE), or Boolean::None. The filters should then provide methods similar to ? and unwrap.