diff --git a/Cargo.lock b/Cargo.lock
index 9b4c1e4..6743a5d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -201,8 +201,11 @@ dependencies = [
"graphql-parser",
"handlebars",
"handlebars_misc_helpers",
+ "minidom",
"once_cell",
"path-dedot",
+ "quick-xml 0.31.0",
+ "quickxml_to_serde",
"regex",
"reqwest",
"rhai",
@@ -811,6 +814,15 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+[[package]]
+name = "minidom"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe549115a674f5ec64c754d85e37d6f42664bd0ef4ffb62b619489ad99c6cb1a"
+dependencies = [
+ "quick-xml 0.17.2",
+]
+
[[package]]
name = "miniz_oxide"
version = "0.7.1"
@@ -1060,6 +1072,37 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "quick-xml"
+version = "0.17.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe1e430bdcf30c9fdc25053b9c459bb1a4672af4617b6c783d7d91dc17c6bbb0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "quick-xml"
+version = "0.31.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
+[[package]]
+name = "quickxml_to_serde"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26f35112b35480fd72f63444289083eeedbd61d13907c82c4309f0ccda35e244"
+dependencies = [
+ "minidom",
+ "serde",
+ "serde_derive",
+ "serde_json",
+]
+
[[package]]
name = "quote"
version = "1.0.33"
diff --git a/codegenr/Cargo.toml b/codegenr/Cargo.toml
index 36c0c6f..3223100 100644
--- a/codegenr/Cargo.toml
+++ b/codegenr/Cargo.toml
@@ -53,6 +53,9 @@ serde_json = { version = "1.0", features = ["preserve_order"] }
serde_yaml = "0.8" # 0.9 failing with deserializing from YAML containing more than one document is not supported on most files
serde = "1.0"
graphql-parser = "0.4"
+quick-xml = { version = "0.31", features = ["serialize"] }
+quickxml_to_serde = "0.5"
+minidom = "0.12"
# Templating
handlebars = { version = "4.4", features = ["script_helper"] }
diff --git a/codegenr/_samples/resolver/plant_catalog.xml b/codegenr/_samples/resolver/plant_catalog.xml
new file mode 100644
index 0000000..4275db9
--- /dev/null
+++ b/codegenr/_samples/resolver/plant_catalog.xml
@@ -0,0 +1,291 @@
+
+
+
+ Bloodroot
+ Sanguinaria canadensis
+ 4
+ Mostly Shady
+ $2.44
+ 031599
+
+
+ Columbine
+ Aquilegia canadensis
+ 3
+ Mostly Shady
+ $9.37
+ 030699
+
+
+ Marsh Marigold
+ Caltha palustris
+ 4
+ Mostly Sunny
+ $6.81
+ 051799
+
+
+ Cowslip
+ Caltha palustris
+ 4
+ Mostly Shady
+ $9.90
+ 030699
+
+
+ Dutchman's-Breeches
+ Dicentra cucullaria
+ 3
+ Mostly Shady
+ $6.44
+ 012099
+
+
+ Ginger, Wild
+ Asarum canadense
+ 3
+ Mostly Shady
+ $9.03
+ 041899
+
+
+ Hepatica
+ Hepatica americana
+ 4
+ Mostly Shady
+ $4.45
+ 012699
+
+
+ Liverleaf
+ Hepatica americana
+ 4
+ Mostly Shady
+ $3.99
+ 010299
+
+
+ Jack-In-The-Pulpit
+ Arisaema triphyllum
+ 4
+ Mostly Shady
+ $3.23
+ 020199
+
+
+ Mayapple
+ Podophyllum peltatum
+ 3
+ Mostly Shady
+ $2.98
+ 060599
+
+
+ Phlox, Woodland
+ Phlox divaricata
+ 3
+ Sun or Shade
+ $2.80
+ 012299
+
+
+ Phlox, Blue
+ Phlox divaricata
+ 3
+ Sun or Shade
+ $5.59
+ 021699
+
+
+ Spring-Beauty
+ Claytonia Virginica
+ 7
+ Mostly Shady
+ $6.59
+ 020199
+
+
+ Trillium
+ Trillium grandiflorum
+ 5
+ Sun or Shade
+ $3.90
+ 042999
+
+
+ Wake Robin
+ Trillium grandiflorum
+ 5
+ Sun or Shade
+ $3.20
+ 022199
+
+
+ Violet, Dog-Tooth
+ Erythronium americanum
+ 4
+ Shade
+ $9.04
+ 020199
+
+
+ Trout Lily
+ Erythronium americanum
+ 4
+ Shade
+ $6.94
+ 032499
+
+
+ Adder's-Tongue
+ Erythronium americanum
+ 4
+ Shade
+ $9.58
+ 041399
+
+
+ Anemone
+ Anemone blanda
+ 6
+ Mostly Shady
+ $8.86
+ 122698
+
+
+ Grecian Windflower
+ Anemone blanda
+ 6
+ Mostly Shady
+ $9.16
+ 071099
+
+
+ Bee Balm
+ Monarda didyma
+ 4
+ Shade
+ $4.59
+ 050399
+
+
+ Bergamot
+ Monarda didyma
+ 4
+ Shade
+ $7.16
+ 042799
+
+
+ Black-Eyed Susan
+ Rudbeckia hirta
+ Annual
+ Sunny
+ $9.80
+ 061899
+
+
+ Buttercup
+ Ranunculus
+ 4
+ Shade
+ $2.57
+ 061099
+
+
+ Crowfoot
+ Ranunculus
+ 4
+ Shade
+ $9.34
+ 040399
+
+
+ Butterfly Weed
+ Asclepias tuberosa
+ Annual
+ Sunny
+ $2.78
+ 063099
+
+
+ Cinquefoil
+ Potentilla
+ Annual
+ Shade
+ $7.06
+ 052599
+
+
+ Primrose
+ Oenothera
+ 3 - 5
+ Sunny
+ $6.56
+ 013099
+
+
+ Gentian
+ Gentiana
+ 4
+ Sun or Shade
+ $7.81
+ 051899
+
+
+ Blue Gentian
+ Gentiana
+ 4
+ Sun or Shade
+ $8.56
+ 050299
+
+
+ Jacob's Ladder
+ Polemonium caeruleum
+ Annual
+ Shade
+ $9.26
+ 022199
+
+
+ Greek Valerian
+ Polemonium caeruleum
+ Annual
+ Shade
+ $4.36
+ 071499
+
+
+ California Poppy
+ Eschscholzia californica
+ Annual
+ Sun
+ $7.89
+ 032799
+
+
+ Shooting Star
+ Dodecatheon
+ Annual
+ Mostly Shady
+ $8.60
+ 051399
+
+
+ Snakeroot
+ Cimicifuga
+ Annual
+ Shade
+ $5.63
+ 071199
+
+
+ Cardinal Flower
+ Lobelia cardinalis
+ 2
+ Shade
+ $3.02
+ 022299
+
+
diff --git a/codegenr/src/loaders/document_path.rs b/codegenr/src/loaders/document_path.rs
index b100f77..8bfbc1e 100644
--- a/codegenr/src/loaders/document_path.rs
+++ b/codegenr/src/loaders/document_path.rs
@@ -82,6 +82,8 @@ impl DocumentPath {
FormatHint::Toml
} else if s.ends_with(".graphql") || s.ends_with(".gql") {
FormatHint::Graphql
+ } else if s.ends_with(".xml") || s.ends_with(".xaml") || s.ends_with(".wsdl") || s.ends_with(".xsd") || s.ends_with(".xul") {
+ FormatHint::Xml
} else {
FormatHint::NoIdea
}
diff --git a/codegenr/src/loaders/mod.rs b/codegenr/src/loaders/mod.rs
index 5874c6e..271fe37 100644
--- a/codegenr/src/loaders/mod.rs
+++ b/codegenr/src/loaders/mod.rs
@@ -7,6 +7,7 @@ pub use document_path::*;
pub mod graphql;
pub mod json;
pub mod toml;
+pub mod xml;
pub mod yaml;
pub trait DocumentLoader {
@@ -48,12 +49,15 @@ pub enum LoaderError {
json_error: serde_json::Error,
yaml_error: serde_yaml::Error,
toml_error: ::toml::de::Error,
+ xml_error: minidom::Error,
graphql_error: graphql_parser::schema::ParseError,
},
#[error("Yaml error: `{0}`.")]
YamlError(#[from] serde_yaml::Error),
#[error("Json error: `{0}`.")]
JsonError(#[from] serde_json::Error),
+ #[error("Xml error: `{0}`.")]
+ XmlError(#[from] minidom::Error),
#[error("Graphql error: `{0}`.")]
GraphqlError(#[from] graphql_parser::schema::ParseError),
#[error("Did not try all the file loaders.")]
@@ -68,6 +72,8 @@ pub(crate) enum FormatHint {
Yaml,
/// The content should be toml
Toml,
+ /// The content should be xml
+ Xml,
/// The content should be a graphql schema
Graphql,
/// We have no f.....g idea
@@ -79,9 +85,10 @@ fn json_from_string(content: &str, hint: FormatHint) -> Result try_loaders(content, &[Json, Yaml, Toml, Graphql]),
- FormatHint::Yaml => try_loaders(content, &[Yaml, Json, Toml, Graphql]),
- FormatHint::Toml => try_loaders(content, &[Toml, Json, Yaml, Graphql]),
- FormatHint::Graphql => try_loaders(content, &[Graphql, Json, Yaml, Toml]),
+ FormatHint::Yaml => try_loaders(content, &[Yaml, Json, Toml, Xml, Graphql]),
+ FormatHint::Toml => try_loaders(content, &[Toml, Json, Yaml, Xml, Graphql]),
+ FormatHint::Xml => try_loaders(content, &[Xml, Json, Yaml, Toml, Graphql]),
+ FormatHint::Graphql => try_loaders(content, &[Graphql, Json, Yaml, Toml, Xml]),
}
}
@@ -90,6 +97,7 @@ fn try_loaders(content: &str, formats: &[FormatHint]) -> Result = None;
let mut yaml_error: Option = None;
let mut toml_error: Option<::toml::de::Error> = None;
+ let mut xml_error: Option<::minidom::Error> = None;
let mut graphql_error: Option = None;
for hint in formats {
@@ -112,6 +120,12 @@ fn try_loaders(content: &str, formats: &[FormatHint]) -> Result e,
});
}
+ FormatHint::Xml => {
+ xml_error = Some(match xml::XmlLoader::json_from_str(content) {
+ Ok(json) => return Ok(json),
+ Err(e) => e,
+ });
+ }
FormatHint::Graphql => {
graphql_error = Some(match graphql::GraphqlLoader::json_from_str(content) {
Ok(json) => return Ok(json),
@@ -129,6 +143,7 @@ fn try_loaders(content: &str, formats: &[FormatHint]) -> Result Result<(), LoaderError> {
+ let _result = DocumentPath::parse("./_samples/resolver/plant_catalog.xml")?.load_raw()?;
+ dbg!(_result);
+ Ok(())
+ }
+
#[allow(clippy::result_large_err)]
#[test]
#[ignore]
diff --git a/codegenr/src/loaders/xml.rs b/codegenr/src/loaders/xml.rs
new file mode 100644
index 0000000..cab971f
--- /dev/null
+++ b/codegenr/src/loaders/xml.rs
@@ -0,0 +1,11 @@
+use super::DocumentLoader;
+use quickxml_to_serde::xml_str_to_json;
+
+pub struct XmlLoader {}
+impl DocumentLoader for XmlLoader {
+ type Error = minidom::Error;
+ fn json_from_str(content: &str) -> Result {
+ let config = quickxml_to_serde::Config::default();
+ xml_str_to_json(content, &config)
+ }
+}
diff --git a/codegenr/src/processor/file.rs b/codegenr/src/processor/file.rs
index 6b1e14d..1c51f6d 100644
--- a/codegenr/src/processor/file.rs
+++ b/codegenr/src/processor/file.rs
@@ -73,7 +73,7 @@ impl Drop for FileLineHandler {
#[cfg(test)]
mod tests {
use super::*;
- use crate::filesystem::make_path_from_root;
+ use crate::filesystem::create_file;
use tempdir::TempDir;
#[test]
@@ -81,7 +81,7 @@ mod tests {
let tmp = TempDir::new("FILE_tests")?;
let instruction = FileInstruction::new(tmp.path().to_string_lossy().into());
let handler = instruction.start(vec!["sub/plop.txt".into()])?;
- let should_exists_path = make_path_from_root(tmp.path(), "sub/plop.txt");
+ let (_file, should_exists_path) = create_file(tmp.path(), "sub/plop.txt")?;
assert!(should_exists_path.exists());
handler.handle_line("hello ...")?;
assert!(should_exists_path.exists());