2 stable releases

new 1.0.1 Jan 29, 2025
1.0.0 Jan 25, 2025

#448 in Parser implementations

Download history 141/week @ 2025-01-23

144 downloads per month

Custom license

58KB
1K SLoC

YES Script

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.

Use Cases

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

Getting Started

This crate provides YesDocParser with two static methods:

  1. pub fn from_file(file: &File, literals: Option<Vec<Literal>>) -> Vec<ParseResult>
    1. Call to parse by file
  2. pub fn from_string(body: &str, literals: Option<Vec<Literal>>) -> Vec<ParseResult>
    1. 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.

See Literal::build_quotes.

Optional Literals

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 {
  // ...
}

Multiline Support

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"

Simple Start

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!

Deep Dive Example

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

License

This project is licensed under the Common Development and Distribution License (CDDL).

No runtime deps