YES
- Your Extensible Script .
Do you want a custom and simple file format but don't want to code the parser? YES is the answer! ✨
YES is a meta scriplet standard whose elements, keys, and evaluation are yours to decide. YES-defined elements can have optional attributes which tag to elements in order to extend their behavior further. This has been proven useful in products which needed to provide UGC (User Generated Content).
Tip
Read the scriptlet standard to learn more.
Your data can mean anything. The parsing is done so the logic is up to you.
YES-compliant parsers can be used:
- to define animation files
- as an extended .OBJ wavefront 3D model format
- as an extended .INI dialect
- as a configuration file
- to implement a scripting language
- to represent character dialog
- to implement a simple network protocol
- and more
This crate provides YesDocParser
with two static methods:
pub fn from_file(file: &File, literals: Option<Vec<Literal>>) -> Vec<ParseResult>
- Call to parse by file
pub fn from_string(body: &str, literals: Option<Vec<Literal>>) -> Vec<ParseResult>
- Call to parse by string
Even if None
is supplied for literals
, the parser will add a pair of quotes for you as the first literal pair to check against while reading.
Literals are character (u8
) pairs which instructs the parser to take every subsequent character in the buffer from Literal::begin
to Literal::end
.
This allows even further extension of the format for your own documents. For example, consider the following line:
var x: [int] = [0, 1, 2, 3, 4, 5]
By providing a custom literal pair [
and ]
, the span [0, 1, 2, 3, 4, 5]
will be stored in the argument [int]
which then allows a programmer to easily determine if that value is correctly notated as an integer array.
Here's how to provide a list of custom literals:
let literals = vec![Literal {begin: '[' as u8, end: ']' as u8,}]; let results = YesDocParser::from_string(content, Some(literals)); for result in result { // ... }
The spec is intended to be simple. Simple to read. Simple to write. Simple to parse.
Therefore newlines \n
were chosen to denote the end of an element. This may not appeal to programmers who are used to bracket notation or semicolons, however non-programmers will appreciate the simplicity.
While simplicity is desired, presentation is just as important.
Elements whose line end with the backslash \
character will defer reading until the last line without the backslash terminator. This allows documents to support elements with arguments which span several lines.
Example:
var long_message: str="\ apple, bananas, coconut, diamond, eggplant,\ fig, grape, horse, igloo, joke, kangaroo,\ lemon, notebook, mango"
Here is a very simple example to show you how to get started:
let content = "frame duration = 1.0s , width = 10, height=20"; let results = YesDocParser::from_string(content, None); let data = match &results.first().unwrap() { ParseResult::Ok { line_number: _, data: Elements::Standard { attrs: _, element }, } => element, _ => panic!("Element expected!"), }; let duration = data.get_key_value_or("duration", "0s".to_owned()); let width = data.get_key_value_or("width", 0); let height = data.get_key_value_or("height", 0); assert_eq!(duration, "1.0s"); assert_eq!(width, 10); assert_eq!(height, 20);
Warning
Be mindful and validate your own document formats!
See how to use the parser to read a custom config file format which enforces document validation, positional arguments, and also contains sub-sections with multiple spanning properties by visiting examples/config.rs
.
cargo run --example config
This project is licensed under the Common Development and Distribution License (CDDL).