scheme-edit 0.1.0

Lossless Scheme S-expression parser and editor (toml_edit-style CST)
Documentation
use scheme_edit::Document;

fn rt(src: &str) {
    let doc = Document::parse(src).unwrap();
    assert_eq!(doc.to_string(), src, "round-trip must be byte-identical");
}

#[test]
fn roundtrips_simple() {
    rt("(list 1 2 3)");
}

#[test]
fn roundtrips_comments_and_weird_ws() {
    rt("; header\n(list\t(channel ; inline\n   (name 'guix)))\n\n");
}

#[test]
fn roundtrips_datum_comment() {
    rt("(list #;(channel (name 'old)) (channel (name 'new)))");
}

#[test]
fn roundtrips_dotted_pair_and_vector() {
    rt("(a . b) #(1 2)");
}

#[test]
fn roundtrips_gexp() {
    rt("#~(string-append #$coreutils \"/bin/ls\")");
}

#[test]
fn roundtrips_quasiquote() {
    rt("`(a ,b ,@(c d))");
}

#[test]
fn unbalanced_close_reports_position() {
    let err = Document::parse("(a))").unwrap_err();
    assert_eq!((err.line, err.col), (1, 4));
}

#[test]
fn unclosed_list_errors() {
    assert!(Document::parse("(a (b)").is_err());
}

#[test]
fn forms_skips_trivia() {
    let doc = Document::parse(";; c\n(use-modules (guix ci))\n\n(list)\n").unwrap();
    let heads: Vec<_> = doc.forms().filter_map(|n| n.head_symbol()).collect();
    assert_eq!(heads, vec!["use-modules", "list"]);
}