Skip to main content

round_trip/
round_trip.rs

1//! Parse + `outer_markup` round-trip. For a defined subset of input,
2//! the parser and serializer are inverses: `parse(src).outer_markup()
3//! == src`.
4//!
5//! Run with: `cargo run --example round_trip -p rdom-parser`
6
7use rdom_core::Dom;
8use rdom_parser::parse;
9
10fn main() {
11    let corpus = [
12        "<div></div>",
13        "<div><span>hi</span></div>",
14        "<br/>",
15        r#"<div class="a b" id="x"><p>Hi</p></div>"#,
16        "<!-- note --><div></div>",
17        "<p>&amp; &lt; &gt;</p>",
18        "<ul><li>one</li><li>two</li><li>three</li></ul>",
19    ];
20
21    let mut all_match = true;
22    for src in &corpus {
23        match round_trip(src) {
24            Ok(out) => {
25                let ok = &out == src;
26                if ok {
27                    println!("✓ {src}");
28                } else {
29                    all_match = false;
30                    println!("✗ {src}");
31                    println!("    → {out}");
32                }
33            }
34            Err(e) => {
35                all_match = false;
36                println!("✗ {src}");
37                println!("    parse error: {e}");
38            }
39        }
40    }
41
42    println!();
43    if all_match {
44        println!("All round-trips match.");
45    } else {
46        println!("Some round-trips diverged (see above).");
47        std::process::exit(1);
48    }
49}
50
51fn round_trip(src: &str) -> Result<String, rdom_parser::ParseError> {
52    let (dom, ids): (Dom<()>, _) = parse(src)?;
53    // For single top-level nodes (most cases), serialize the node
54    // itself; for multi-top-level (like "<!-- … --><div></div>"),
55    // serialize the fragment root's inner markup.
56    let out = if ids.len() == 1 {
57        dom.outer_markup(ids[0])
58    } else {
59        dom.inner_markup(dom.root())
60    };
61    Ok(out)
62}