eure

Macro eure 

Source
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"
});