diff --git a/Cargo.lock b/Cargo.lock index ccf405b..d3299bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,37 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "either" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" + [[package]] name = "heck" version = "0.5.0" @@ -149,12 +180,33 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rxml" -version = "2.3.0" +version = "2.3.1" dependencies = [ "pyo3", "quick-xml", + "rayon", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7b4627e..d14ccee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rxml" -version = "2.3.0" +version = "2.3.1" edition = "2021" [lib] @@ -10,3 +10,4 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.23.5" quick-xml = "0.37.2" +rayon = "1.10" \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 0c8383a..eb549e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ classifiers = [ "Typing :: Typed", "License :: OSI Approved :: MIT License", ] -version = "2.3.0" +version = "2.3.1" [tool.maturin] diff --git a/src/entities.rs b/src/entities.rs index 8a862c6..d25316b 100644 --- a/src/entities.rs +++ b/src/entities.rs @@ -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)] @@ -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::>>()?; 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, @@ -185,18 +182,23 @@ impl Node { } pub fn to_dict(&self) -> HashMap { - 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()), + ), + ]) } } @@ -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")), ) diff --git a/src/read.rs b/src/read.rs index 648d67f..3971ca6 100644 --- a/src/read.rs +++ b/src/read.rs @@ -22,7 +22,7 @@ fn get_attrs(attrs: Attributes) -> HashMap { 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, @@ -30,7 +30,7 @@ fn read_node(root_tag: String, reader: &mut Reader<&[u8]>) -> Node { 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()); } _ => { @@ -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, diff --git a/src/write.rs b/src/write.rs index 944e9ec..2440691 100644 --- a/src/write.rs +++ b/src/write.rs @@ -64,29 +64,30 @@ pub fn write_string(node: Node, indent: Option, default_xml_def: Option 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 @@ -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);