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. - Message Emission: Use
-
to emit a single message and++
to emit multiple messages. - Conditional Emission: The
then_emit
andor_emit
operators allow conditional message emission based on boolean conditions. - Indentation Control:
IND
andSET_INDENT
functions to manage indentation dynamically. - Flexible Data Handling: Supports arrays, maps, strings, and custom types.
- Shortcuts:
IND
andNL
constants can be used as shortcuts forIND(1)
andNL(1)
respectively.
§DSL Overview
- <message>
: Emits a message.<a> ++ <b>
: Emits messagesa
andb
.then_emit(<condition>, <message>)
: Emits<message>
if<condition>
is true.or_emit(<condition>, <message>)
: Emits<message>
if<condition>
is false.SET_INDENT(<string>)
: Sets the current indent string.IND(<count>)
: Generates indentation with the current indent string.NL(<count>)
: Inserts newlines.IND
: Shortcut forIND(1)
.NL
: Shortcut forNL(1)
.
§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; // ++ emits the message and concatenates it
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::{
rhai::{CustomType, TypeBuilder},
FormattingEngine,
};
#[derive(Clone, CustomType)]
struct Person {
pub name: String,
pub age: i32,
}
let mut engine = FormattingEngine::new(false);
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; // ++ emits the message and concatenates it
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();
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
.