macro_rules! eure {
({}) => { ... };
({ $($body:tt)* }) => { ... };
(@value_tt null) => { ... };
(@value_tt true) => { ... };
(@value_tt false) => { ... };
(@value_tt $v:literal) => { ... };
(@value_tt $v:expr) => { ... };
(@array_items $c:ident;) => { ... };
(@array_items $c:ident; , $($rest:tt)*) => { ... };
(@array_items $c:ident; @ code ($content:literal) $($rest:tt)*) => { ... };
(@array_items $c:ident; @ code ($lang:literal, $content:literal) $($rest:tt)*) => { ... };
(@array_items $c:ident; [$($inner:tt)*] $($rest:tt)*) => { ... };
(@array_items $c:ident; ($($inner:tt)*) $($rest:tt)*) => { ... };
(@array_items $c:ident; $item:tt $($rest:tt)*) => { ... };
(@tuple_items $c:ident $idx:expr;) => { ... };
(@tuple_items $c:ident $idx:expr; , $($rest:tt)*) => { ... };
(@tuple_items $c:ident $idx:expr; @ code ($content:literal) $($rest:tt)*) => { ... };
(@tuple_items $c:ident $idx:expr; @ code ($lang:literal, $content:literal) $($rest:tt)*) => { ... };
(@tuple_items $c:ident $idx:expr; [$($inner:tt)*] $($rest:tt)*) => { ... };
(@tuple_items $c:ident $idx:expr; ($($inner:tt)*) $($rest:tt)*) => { ... };
(@tuple_items $c:ident $idx:expr; $item:tt $($rest:tt)*) => { ... };
(@object_key $key:ident) => { ... };
(@object_key $key:tt) => { ... };
(@object_items $c:ident;) => { ... };
(@object_items $c:ident; , $($rest:tt)*) => { ... };
(@object_items $c:ident; $key:tt => @ code ($content:literal) $($rest:tt)*) => { ... };
(@object_items $c:ident; $key:tt => @ code ($lang:literal, $content:literal) $($rest:tt)*) => { ... };
(@object_items $c:ident; $key:tt => [$($inner:tt)*] $($rest:tt)*) => { ... };
(@object_items $c:ident; $key:tt => ($($inner:tt)*) $($rest:tt)*) => { ... };
(@object_items $c:ident; $key:tt => $val:tt $($rest:tt)*) => { ... };
(@stmt $c:ident;) => { ... };
(@stmt $c:ident; , $($rest:tt)*) => { ... };
(@stmt $c:ident; = ! $($rest:tt)*) => { ... };
(@stmt $c:ident; = - $v:literal $($rest:tt)*) => { ... };
(@stmt $c:ident; = @ code ($content:literal) $($rest:tt)*) => { ... };
(@stmt $c:ident; = @ code ($lang:literal, $content:literal) $($rest:tt)*) => { ... };
(@stmt $c:ident; = @ block ($content:literal) $($rest:tt)*) => { ... };
(@stmt $c:ident; = @ block ($lang:literal, $content:literal) $($rest:tt)*) => { ... };
(@stmt $c:ident; = [] $($rest:tt)*) => { ... };
(@stmt $c:ident; = [$($items:tt)+] $($rest:tt)*) => { ... };
(@stmt $c:ident; = () $($rest:tt)*) => { ... };
(@stmt $c:ident; = ($($items:tt)+) $($rest:tt)*) => { ... };
(@stmt $c:ident; = { $key:tt => $($inner:tt)+ } $($rest:tt)*) => { ... };
(@stmt $c:ident; = $v:tt $($rest:tt)*) => { ... };
(@stmt $c:ident; @ $seg:ident $($rest:tt)*) => { ... };
(@stmt $c:ident; $($tokens:tt)+) => { ... };
(@section_after_seg $c:ident $scope:ident; . $seg:ident $($rest:tt)*) => { ... };
(@section_after_seg $c:ident $scope:ident; = $v:tt $($rest:tt)*) => { ... };
(@section_after_seg $c:ident $scope:ident; {} $($rest:tt)*) => { ... };
(@section_after_seg $c:ident $scope:ident; { $($inner:tt)+ } $($rest:tt)*) => { ... };
(@section_after_seg $c:ident $scope:ident; $($rest:tt)*) => { ... };
(@section_bindings $c:ident $scope:ident;) => { ... };
(@section_bindings $c:ident $scope:ident; , $($rest:tt)*) => { ... };
(@section_bindings $c:ident $scope:ident; @ $seg:ident $($rest:tt)*) => { ... };
(@section_bindings $c:ident $scope:ident; $($tokens:tt)+) => { ... };
(@section_path $c:ident $section_scope:ident $scope:ident; $seg:ident $($rest:tt)*) => { ... };
(@section_path $c:ident $section_scope:ident $scope:ident; % $ext:ident $($rest:tt)*) => { ... };
(@section_path $c:ident $section_scope:ident $scope:ident; % $ext:literal $($rest:tt)*) => { ... };
(@section_path $c:ident $section_scope:ident $scope:ident; # $idx:literal $($rest:tt)*) => { ... };
(@section_path $c:ident $section_scope:ident $scope:ident; ($($tuple:tt)*) $($rest:tt)*) => { ... };
(@section_path $c:ident $section_scope:ident $scope:ident; $key:literal $($rest:tt)*) => { ... };
(@section_after_path $c:ident $section_scope:ident $scope:ident; [$($arr:tt)*] $($rest:tt)*) => { ... };
(@section_after_path $c:ident $section_scope:ident $scope:ident; $($rest:tt)*) => { ... };
(@section_array_marker $c:ident $section_scope:ident $scope:ident []; $($rest:tt)*) => { ... };
(@section_array_marker $c:ident $section_scope:ident $scope:ident [$idx:literal]; $($rest:tt)*) => { ... };
(@section_terminal $c:ident $section_scope:ident $scope:ident; . $($rest:tt)+) => { ... };
(@section_terminal $c:ident $section_scope:ident $scope:ident; = ! $($rest:tt)*) => { ... };
(@section_terminal $c:ident $section_scope:ident $scope:ident; = @ code ($content:literal) $($rest:tt)*) => { ... };
(@section_terminal $c:ident $section_scope:ident $scope:ident; = @ code ($lang:literal, $content:literal) $($rest:tt)*) => { ... };
(@section_terminal $c:ident $section_scope:ident $scope:ident; = @ block ($content:literal) $($rest:tt)*) => { ... };
(@section_terminal $c:ident $section_scope:ident $scope:ident; = @ block ($lang:literal, $content:literal) $($rest:tt)*) => { ... };
(@section_terminal $c:ident $section_scope:ident $scope:ident; = $v:tt $($rest:tt)*) => { ... };
(@section_terminal $c:ident $section_scope:ident $scope:ident; {} $($rest:tt)*) => { ... };
(@section_terminal $c:ident $section_scope:ident $scope:ident; { $($inner:tt)+ } $($rest:tt)*) => { ... };
(@path $c:ident $scope:ident; $seg:ident $($rest:tt)*) => { ... };
(@path $c:ident $scope:ident; % $ext:ident $($rest:tt)*) => { ... };
(@path $c:ident $scope:ident; % $ext:literal $($rest:tt)*) => { ... };
(@path $c:ident $scope:ident; # $idx:literal $($rest:tt)*) => { ... };
(@path $c:ident $scope:ident; ($($tuple:tt)*) $($rest:tt)*) => { ... };
(@path $c:ident $scope:ident; $key:literal $($rest:tt)*) => { ... };
(@build_tuple_key;) => { ... };
(@build_tuple_key; $($item:expr),+ $(,)?) => { ... };
(@after_path $c:ident $scope:ident; [$($arr:tt)*] $($rest:tt)*) => { ... };
(@after_path $c:ident $scope:ident; $($rest:tt)*) => { ... };
(@array_marker $c:ident $scope:ident []; $($rest:tt)*) => { ... };
(@array_marker $c:ident $scope:ident [$idx:literal]; $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; . $($rest:tt)+) => { ... };
(@terminal $c:ident $scope:ident; = ! $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = - $v:literal $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = @ code ($content:literal) $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = @ code ($lang:literal, $content:literal) $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = @ block ($content:literal) $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = @ block ($lang:literal, $content:literal) $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = [] $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = [$($items:tt)+] $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = () $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = ($($items:tt)+) $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = { $key:tt => $($inner:tt)+ } $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; = $v:tt $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; {} $($rest:tt)*) => { ... };
(@terminal $c:ident $scope:ident; { $($inner:tt)+ } $($rest:tt)*) => { ... };
}Expand description
A declarative macro for building Eure documents, inspired by serde_json’s json! macro.
§Syntax
The macro uses a TT muncher pattern to support arbitrary path combinations:
- Idents:
a.b.c - Extensions:
a.%ext(use%instead of$since$is reserved in macros) - Tuple index:
a.#0,a.#1 - Array markers:
a[](push),a[0](index) - Tuple keys:
a.(1, "key")(composite map keys) - Mixed paths:
a.%ext[].b,a[].%ext.#0,a.(1, 2).name
§Special Values
null: Creates a null value!: Creates an unbound hole (explicit placeholder)@code("content"): Creates inline code with implicit language@code("lang", "content"): Creates inline code with explicit language@block("content"): Creates block code with implicit language@block("lang", "content"): Creates block code with explicit language
§Examples
use eure_document::eure;
// Simple assignment (commas are optional)
let doc = eure!({
name = "Alice"
age = 30
});
// Null and hole values
let doc = eure!({
optional = null
placeholder = !
});
// Code values
let doc = eure!({
snippet = @code("let x = 1")
sql = @code("sql", "SELECT * FROM users")
script = @block("fn main() {}")
rust_code = @block("rust", "fn main() {\n println!(\"Hello\");\n}")
});
// Nested paths
let doc = eure!({
user.name = "Bob"
user.active = true
});
// Blocks (for grouping)
let doc = eure!({
user {
name = "Charlie"
role = "admin"
}
});
// Extensions
let doc = eure!({
field.%variant = @code("text")
});
// Tuple index
let doc = eure!({
point.#0 = 1.0f64
point.#1 = 2.0f64
});
// Array markers
let doc = eure!({
items[] = 1
items[] = 2
});
// Tuple keys (composite map keys)
let doc = eure!({
map.(1, "key") = "value"
map.(true, 2) = "another"
});
// Arrays (literal)
let doc = eure!({
tags = ["a", "b", "c"]
});
// Tuples (literal)
let doc = eure!({
point = (1.0f64, 2.0f64)
});
// Sections (like TOML)
let doc = eure!({
@user
name = "Alice"
age = 30
@settings
theme = "dark"
});