Crates.io | cirru_parser |
lib.rs | cirru_parser |
version | 0.1.35 |
created_at | 2021-04-13 16:16:16.562013+00 |
updated_at | 2025-09-13 04:36:56.258432+00 |
description | Parser for Cirru text syntax |
homepage | http://cirru.org |
repository | https://github.com/Cirru/parser.rs |
max_upload_size | |
id | 382968 |
size | 71,509 |
This crate provides a parser for the Cirru text syntax, an indentation-based syntax that can be used as a replacement for S-Expressions. It's designed to be simple, clean, and easy to read.
For example, this Cirru code:
defn fib (x)
if (<= x 2) 1
+
fib $ dec x
fib $ - x 2
is parsed into a tree structure that represents the nested expressions:
[ ["defn" "fib" [ "x" ]
[ "if" [ "<=" "x" "2" ] "1"
[ "+" [ "fib" ["dec" "x"] ] [ "fib" ["-" "x" "2"] ] ]
]
] ]
Add this to your Cargo.toml
:
[dependencies]
cirru_parser = "0.1.33"
To parse a string of Cirru code, use the parse
function. It returns a Result<Vec<Cirru>, String>
, where Cirru
is an enum representing either a leaf (string) or a list of Cirru
expressions.
use cirru_parser::{parse, Cirru};
fn main() -> Result<(), String> {
let code = "defn main\n println \"Hello, world!\"";
let tree = parse(code)?;
let expected = vec![
Cirru::List(vec![
Cirru::Leaf("defn".into()),
Cirru::Leaf("main".into()),
Cirru::List(vec![
Cirru::Leaf("println".into()),
Cirru::Leaf("Hello, world!".into()),
]),
]),
];
assert_eq!(tree, expected);
Ok(())
}
This crate also provides a format
function to convert a Cirru
tree back into a string. You can control the output format with CirruWriterOptions
.
use cirru_parser::{parse, format, CirruWriterOptions};
let code = "a (b c)";
let tree = parse(code).unwrap();
let options = CirruWriterOptions { use_inline: true };
let formatted_code = format(&tree, options).unwrap();
assert_eq!(formatted_code, "a (b c)");
When creating Cirru code programmatically, you might need to escape strings to ensure they are treated as single leaves, especially if they contain spaces or special characters.
use cirru_parser::escape_cirru_leaf;
let escaped = escape_cirru_leaf("a b");
assert_eq!(escaped, "\"a b\"");
This crate provides the following features:
Default features:
Cirru
type implements Serialize
and Deserialize
traits by default, allowing integration with any serde-compatible serialization format (bincode, MessagePack, etc.).Optional features:
from_json_str
, to_json_str
, etc.) for converting between Cirru structures and JSON.To use JSON conversion features, add them to your Cargo.toml
:
[dependencies]
cirru_parser = { version = "0.1.33", features = ["serde-json"] }
use cirru_parser::Cirru;
// Basic usage (always available)
let data = Cirru::leaf("hello");
// Serde serialization (always available)
use serde_json;
let json = serde_json::to_string(&data).unwrap();
// JSON conversion (requires "serde-json" feature)
#[cfg(feature = "serde-json")]
{
use cirru_parser::from_json_str;
let cirru = from_json_str(r#"["a", ["b", "c"]]"#).unwrap();
}
Contributions are welcome! Here's how to get started:
cargo test
cargo bench
cargo clippy
This project is licensed under the MIT License.