Expand description
Simple DSL for formatting data based on Rhai.
This crate provides a custom DSL built on top of the Rhai scripting engine, designed specifically for formatting data. The DSL introduces a set of custom functions and operators to enhance the capabilities of Rhai when it comes to text formatting tasks.
§Key Features
- Custom Operators: Extended with operators like
++
,and
,or
,xor
,contains
,equals
,require
,then_emit
, andor_emit
for expressive scripts. - Value/Text Emission: Use
~
to emit a single value - Concatenate multiple values: Use
++
to stringify and concatenate multiple values. - Conditional Emission: The
then_emit
andor_emit
operators allow conditional value emission based on boolean conditions. - Indentation Control:
IND
andSET_INDENT
functions to manage indentation dynamically. - Flexible Data Handling: Supports vector, maps, strings, and custom types.
- Shortcuts:
IND
andNL
constants can be used as shortcuts forIND(1)
andNL(1)
respectively.
§DSL Overview
~ <value>
: Emits a value.<a> ++ <b>
: Concatenates valuesa
andb
.<condition> then_emit <value>
: Returns<value>
if<condition>
is true.<condition> or_emit <value>
: Returns<value>
if<condition>
is false.SET_INDENT(<string>)
: Sets the current indent string.IND(<count>)
: Returns the currently set indent string for<count>
times.NL(<count>)
: Returns<count>
newlines.IND
: Shortcut forIND(1)
.NL
: Shortcut forNL(1)
.<vector> require <number> to_be <value>
: Throws an error if not exactly<number>
ofare found. <a> contains <b>
: Checks if<a>
is part of<b>
.<value> equals <value>
: Checks if two maps are equal.<vector> any <value>
: Checks if any of the values in<vector>
is equal to<value>
.<vector> all <value>
: Checks if all of the values in<vector>
are equal to<value>
.<vector> none <value>
: Checks if none of the values in<vector>
are equal to<value>
.<a> and <b>
: Logical AND operation.<a> or <b>
: Logical OR operation.<a> xor <b>
: Logical XOR operation.
§DSL Example
We’re going to use the following script to format a person’s details:
SET_INDENT(".. "); // sets the current indent string to ".. "
~ "Person Details:"; // ~ emits a single message
~ NL; // NL emits a newline
~ IND ++ "Name: " ++ person.name ++ NL; // ++ concatenates the values
~ IND ++ "Age: " ++ person.age ++ NL; // ++ automatically converts the values to strings
~ IND(2); // custom operator IND indents the message
~ person.age > 18 then_emit("- Adult"); // custom operator then_emit emits a message conditionally
use script_format::{
// The crate re-exports the Rhai engine for convenience
rhai::{CustomType, TypeBuilder},
FormattingEngine,
};
// Derive the `CustomType` trait to enable Rhai to access the fields of the struct
#[derive(Clone, CustomType)]
struct Person {
pub name: String,
pub age: i32,
}
// Create a new `FormattingEngine` instance with debug mode disabled
let mut engine = FormattingEngine::new(false);
// Register the custom type so the Rhai engine can access it
engine.build_type::<Person>();
let person = Person {
name: "Alice".into(),
age: 30,
};
let script = r#"
SET_INDENT(".. "); // sets the current indent string to ".. "
~ "Person Details:"; // ~ emits a single message
~ NL; // NL emits a newline
~ IND ++ "Name: " ++ person.name ++ NL; // ++ concatenates the values
~ IND ++ "Age: " ++ person.age ++ NL; // ++ automatically converts the values to strings
~ IND(2); // custom operator IND indents the message
~ person.age > 18 then_emit("- Adult"); // custom operator then_emit emits a message conditionally
"#;
let expected = r#"
Person Details:
.. Name: Alice
.. Age: 30
.. .. - Adult
"#
.trim();
// Execute the Rhai script to format the person's details
let result = engine.format("person", person, script);
assert_eq!(result.unwrap(), expected);
Expected Output:
Name: Alice
Age: 30 - Adult
This DSL is ideal for generating formatted text dynamically based on data inputs.
Re-exports§
pub use rhai;
Structs§
- Formatting
Engine - A wrapper around the Rhai
Engine
for formatting data using a dsl based on rhai.
Type Aliases§
- Script
Result - A type alias for the result of script execution within the
FormattingEngine
.