Skip to content

Commit

Permalink
Initial work on XML support.
Browse files Browse the repository at this point in the history
  • Loading branch information
01mf02 committed Feb 8, 2025
1 parent 419a76c commit 460e55c
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = [
"jaq-core",
"jaq-std",
"jaq-json",
"jaq-xml",
"jaq",
"jaq-play",
]
Expand Down
7 changes: 7 additions & 0 deletions jaq-xml/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "jaq-xml"
version = "0.1.0"
edition = "2021"

[dependencies]
quick-xml = {version = "0.37.2", features = []}
63 changes: 63 additions & 0 deletions jaq-xml/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use quick_xml::errors::{Error, Result};
use quick_xml::events::attributes::Attribute;
use quick_xml::events::{BytesStart, BytesText, Event};
use quick_xml::reader::Reader;

#[derive(Debug)]
enum Node {
Tac(String, Vec<(String, String)>, Vec<Node>),

Check failure on line 8 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build i686-unknown-linux-gnu

fields `0`, `1`, and `2` are never read

Check failure on line 8 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build x86_64-unknown-linux-gnu

fields `0`, `1`, and `2` are never read
Text(String),

Check failure on line 9 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build i686-unknown-linux-gnu

field `0` is never read

Check failure on line 9 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build x86_64-unknown-linux-gnu

field `0` is never read
Comment(String),

Check failure on line 10 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build i686-unknown-linux-gnu

field `0` is never read

Check failure on line 10 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build x86_64-unknown-linux-gnu

field `0` is never read
Doctype(String),

Check failure on line 11 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build i686-unknown-linux-gnu

field `0` is never read

Check failure on line 11 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build x86_64-unknown-linux-gnu

field `0` is never read
Pi(String),

Check failure on line 12 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build i686-unknown-linux-gnu

field `0` is never read

Check failure on line 12 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build x86_64-unknown-linux-gnu

field `0` is never read
}

fn parse_many(read: &mut Reader<&[u8]>, root: bool) -> Result<Vec<Node>> {
core::iter::from_fn(|| parse2(read, root).transpose()).collect()
}

fn parse2(read: &mut Reader<&[u8]>, root: bool) -> Result<Option<Node>> {
let u8_str = |u: &[u8]| {
std::str::from_utf8(u)
.map_err(|e| Error::Encoding(e.into()))
.map(|s| s.to_owned())
};
let text_str = |t: BytesText| t.unescape().map(|s| s.into_owned());
let attr =
|a: Attribute| Ok::<_, Error>((u8_str(a.key.as_ref())?, a.unescape_value()?.into_owned()));
let attrs = |s: BytesStart| s.attributes().map(|a| Ok(attr(a?)?)).collect::<Result<_>>();

Ok(Some(match read.read_event()? {
Event::End(_) => return Ok(None),
Event::Eof if root => return Ok(None),
Event::Eof => panic!(),
Event::Start(start) => {
let tag = u8_str(start.name().as_ref())?;
Node::Tac(tag, attrs(start)?, parse_many(read, false)?)
}
Event::Empty(start) => {
let tag = u8_str(start.name().as_ref())?;
Node::Tac(tag, attrs(start)?, Vec::new())
}
Event::Text(e) => Node::Text(text_str(e)?),
Event::Comment(e) => Node::Comment(text_str(e)?),
Event::PI(pi) => Node::Pi(u8_str(&pi)?),
Event::CData(cd) => Node::Text(u8_str(&cd.into_inner())?),
Event::DocType(dt) => Node::Doctype(text_str(dt)?),
Event::Decl(d) => Node::Pi(u8_str(&d)?),
}))
}

fn main() {
let xml = r#"<?xml version = '1.0' ?><tag1 att1 = "test">
<bla/>
<?bla blu?>
<tag2><!--Test comment-->Test</tag2>
<tag2>Test 2</tag2>
</tag1>"#;
let mut read = Reader::from_str(xml);
read.config_mut().trim_text(true);

let nodes = parse_many(&mut read, true);
dbg!(nodes);

Check failure on line 62 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build i686-unknown-linux-gnu

unused `Result` that must be used

Check failure on line 62 in jaq-xml/src/main.rs

View workflow job for this annotation

GitHub Actions / build x86_64-unknown-linux-gnu

unused `Result` that must be used
}

0 comments on commit 460e55c

Please sign in to comment.