Skip to content

Commit 370932e

Browse files
authored
feat: add XML format support (read/write) (#54)
Adds XML as a fully supported format alongside JSON, YAML, TOML, and CSV. - Parser: elements → maps, repeated elements → arrays, attributes with configurable prefix (@), CDATA, mixed content (#text), namespaces - Writer: maps → elements, arrays → repeated tags, @-prefixed keys → attributes, XML declaration, special-character escaping - Configurable attribute prefix and root element name via XmlConfig - Comprehensive tests: parsing, serialization, round-trips, edge cases - CLI integration: -f xml / -t xml, auto-detect from .xml extension Fixes #25
1 parent 13e7bd7 commit 370932e

File tree

5 files changed

+898
-2
lines changed

5 files changed

+898
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ serde_yaml = "0.9"
1414
toml = "0.8"
1515
csv = "1"
1616
clap = { version = "4", features = ["derive"] }
17+
quick-xml = "0.31"
1718
indexmap = { version = "2", features = ["serde"] }
1819
thiserror = "1"
1920
anyhow = "1"

src/cli.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub enum Format {
99
Yaml,
1010
Toml,
1111
Csv,
12+
Xml,
1213
}
1314

1415
impl Format {
@@ -19,6 +20,7 @@ impl Format {
1920
(Format::Yaml, "YAML", &["yaml", "yml"]),
2021
(Format::Toml, "TOML", &["toml"]),
2122
(Format::Csv, "CSV", &["csv"]),
23+
(Format::Xml, "XML", &["xml"]),
2224
]
2325
}
2426

@@ -29,6 +31,7 @@ impl Format {
2931
"yaml" | "yml" => Some(Format::Yaml),
3032
"toml" => Some(Format::Toml),
3133
"csv" => Some(Format::Csv),
34+
"xml" => Some(Format::Xml),
3235
_ => None,
3336
}
3437
}
@@ -47,6 +50,7 @@ impl Format {
4750
"yaml" | "yml" => Some(Format::Yaml),
4851
"toml" => Some(Format::Toml),
4952
"csv" => Some(Format::Csv),
53+
"xml" => Some(Format::Xml),
5054
_ => None,
5155
}
5256
}
@@ -59,6 +63,7 @@ impl fmt::Display for Format {
5963
Format::Yaml => write!(f, "yaml"),
6064
Format::Toml => write!(f, "toml"),
6165
Format::Csv => write!(f, "csv"),
66+
Format::Xml => write!(f, "xml"),
6267
}
6368
}
6469
}
@@ -184,6 +189,7 @@ pub fn parse_input(input: &str, format: Format) -> crate::error::Result<crate::v
184189
Format::Yaml => crate::formats::yaml::from_str(input),
185190
Format::Toml => crate::formats::toml::from_str(input),
186191
Format::Csv => crate::formats::csv::from_str(input),
192+
Format::Xml => crate::formats::xml::from_str(input),
187193
}
188194
}
189195

@@ -204,6 +210,7 @@ pub fn serialize_output(
204210
Format::Yaml => crate::formats::yaml::to_string(value),
205211
Format::Toml => crate::formats::toml::to_string(value),
206212
Format::Csv => crate::formats::csv::to_string(value),
213+
Format::Xml => crate::formats::xml::to_string(value),
207214
}
208215
}
209216

@@ -353,6 +360,11 @@ mod tests {
353360
assert_eq!(Format::from_extension("xyz"), None);
354361
}
355362

363+
#[test]
364+
fn format_from_extension_xml() {
365+
assert_eq!(Format::from_extension("xml"), Some(Format::Xml));
366+
}
367+
356368
#[test]
357369
fn format_from_path_json() {
358370
let p = PathBuf::from("data.json");
@@ -375,7 +387,8 @@ mod tests {
375387
assert_eq!(Format::from_name("yaml"), Some(Format::Yaml));
376388
assert_eq!(Format::from_name("toml"), Some(Format::Toml));
377389
assert_eq!(Format::from_name("csv"), Some(Format::Csv));
378-
assert_eq!(Format::from_name("xml"), None);
390+
assert_eq!(Format::from_name("xml"), Some(Format::Xml));
391+
assert_eq!(Format::from_name("nope"), None);
379392
}
380393

381394
// -- Arg parsing --------------------------------------------------------
@@ -488,6 +501,7 @@ mod tests {
488501
assert_eq!(Format::Yaml.to_string(), "yaml");
489502
assert_eq!(Format::Toml.to_string(), "toml");
490503
assert_eq!(Format::Csv.to_string(), "csv");
504+
assert_eq!(Format::Xml.to_string(), "xml");
491505
}
492506

493507
// -- Mapping CLI flags --------------------------------------------------

src/formats/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod csv;
22
pub mod json;
33
pub mod toml;
4+
pub mod xml;
45
pub mod yaml;

0 commit comments

Comments
 (0)