Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rxml"
version = "2.3.0"
version = "2.3.1"
edition = "2021"

[lib]
Expand All @@ -10,3 +10,4 @@ crate-type = ["cdylib"]
[dependencies]
pyo3 = "0.23.5"
quick-xml = "0.37.2"
rayon = "1.10"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ classifiers = [
"Typing :: Typed",
"License :: OSI Approved :: MIT License",
]
version = "2.3.0"
version = "2.3.1"


[tool.maturin]
Expand Down
58 changes: 30 additions & 28 deletions src/entities.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![allow(clippy::only_used_in_recursion)]
use crate::f_str;
use pyo3::{prelude::*, types::PyType};
use rayon::prelude::*;
use std::collections::HashMap;

#[derive(Clone, FromPyObject, IntoPyObject, Eq, PartialEq, Debug)]
Expand Down Expand Up @@ -154,28 +155,24 @@ impl Node {
Some(HashmapTypes::String(n)) => n,
_ => return Err(pyo3::exceptions::PyValueError::new_err("Invalid name")),
}
.to_owned();
let temp_attrs = match dict_.get("attrs") {
.clone();
let attrs = match dict_.get("attrs") {
Some(HashmapTypes::Map(a)) => a,
_ => return Err(pyo3::exceptions::PyValueError::new_err("Invalid attrs")),
};
let temp_children = match dict_.get("children") {
}
.clone();
let children = match dict_.get("children") {
Some(HashmapTypes::Vec(c)) => c,
_ => return Err(pyo3::exceptions::PyValueError::new_err("Invalid children")),
};
}
.iter()
.map(|child| Node::from_dict(cls, child.clone()))
.collect::<PyResult<Vec<Node>>>()?;
let text = match dict_.get("text") {
Some(HashmapTypes::NullableString(t)) => t.to_owned(),
Some(HashmapTypes::String(t)) => Some(t.to_owned()),
Some(HashmapTypes::NullableString(t)) => t.clone(),
Some(HashmapTypes::String(t)) => Some(t.clone()),
_ => None,
};
let mut attrs = HashMap::new();
for (k, v) in temp_attrs {
attrs.insert(k.to_owned(), v.to_owned());
}
let mut children = Vec::new();
for child in temp_children {
children.push(Node::from_dict(cls, child.clone())?);
}
Ok(Self {
name,
attrs,
Expand All @@ -185,18 +182,23 @@ impl Node {
}

pub fn to_dict(&self) -> HashMap<String, HashmapTypes> {
let mut map = HashMap::new();
map.insert(f_str!("name"), HashmapTypes::String(self.name.clone()));
map.insert(f_str!("attrs"), HashmapTypes::Map(self.attrs.clone()));
map.insert(
f_str!("children"),
HashmapTypes::Vec(self.children.iter().map(|child| child.to_dict()).collect()),
);
map.insert(
f_str!("text"),
HashmapTypes::NullableString(self.text.clone()),
);
map
HashMap::from([
(f_str!("name"), HashmapTypes::String(self.name.clone())),
(f_str!("attrs"), HashmapTypes::Map(self.attrs.clone())),
(
f_str!("children"),
HashmapTypes::Vec(
self.children
.par_iter()
.map(|child| child.to_dict())
.collect(),
),
),
(
f_str!("text"),
HashmapTypes::NullableString(self.text.clone()),
),
])
}
}

Expand Down Expand Up @@ -234,7 +236,7 @@ mod tests {
.unwrap();
let second_child_node = Node::new(
f_str!("test new"),
Some(attrs.clone()),
Some(attrs),
Some(Vec::new()),
Some(f_str!("test")),
)
Expand Down
6 changes: 3 additions & 3 deletions src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ fn get_attrs(attrs: Attributes) -> HashMap<String, String> {
fn read_node(root_tag: String, reader: &mut Reader<&[u8]>) -> Node {
let mut buf = Vec::new();
let mut root = Node {
name: root_tag.clone(),
name: root_tag,
attrs: HashMap::new(),
children: Vec::new(),
text: None,
};
loop {
match reader.read_event_into(&mut buf) {
Ok(Event::Start(e)) => match e.name().as_ref() {
_e if _e == root_tag.as_bytes() => {
_e if _e == root.name.as_bytes() => {
root.attrs = get_attrs(e.attributes());
}
_ => {
Expand All @@ -52,7 +52,7 @@ fn read_node(root_tag: String, reader: &mut Reader<&[u8]>) -> Node {
Ok(Event::Text(e)) => {
root.text = Some(f_str!(e.unescape().unwrap()));
}
Ok(Event::End(e)) if e.name().as_ref() == root_tag.as_bytes() => {
Ok(Event::End(e)) if e.name().as_ref() == root.name.as_bytes() => {
break;
}
Ok(Event::Eof) => break,
Expand Down
20 changes: 8 additions & 12 deletions src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,29 +64,30 @@ pub fn write_string(node: Node, indent: Option<usize>, default_xml_def: Option<b
#[cfg(test)]
mod tests {
use crate::entities::Node;
use crate::f_str;
use crate::write::{write_file, write_node_to_string, write_string};
use std::collections::HashMap;
use std::fs::{read_to_string, remove_file};
fn root_node() -> Node {
let mut attrs = HashMap::new();
attrs.insert("test".to_string(), "test".to_string());
attrs.insert(f_str!("test"), f_str!("test"));
let mut root = Node {
name: "root".to_string(),
name: f_str!("root"),
attrs: attrs.clone(),
children: Vec::new(),
text: None,
};
let mut child = Node {
name: "child".to_string(),
attrs: attrs.clone(),
name: f_str!("child"),
attrs,
children: Vec::new(),
text: None,
};
child.children.push(Node {
name: "child".to_string(),
name: f_str!("child"),
attrs: HashMap::new(),
children: Vec::new(),
text: Some("test".to_string()),
text: Some(f_str!("test")),
});
root.children.push(child);
root
Expand All @@ -112,12 +113,7 @@ mod tests {
fn test_write_file() {
let root = root_node();
let expected = expected_file();
write_file(
root,
"tests/test_write.xml".to_string(),
Some(4),
Some(true),
);
write_file(root, f_str!("tests/test_write.xml"), Some(4), Some(true));
let file_str = read_to_string("tests/test_write.xml").unwrap();
remove_file("tests/test_write.xml").unwrap();
assert_eq!(file_str, expected);
Expand Down