diff --git a/.gitignore b/.gitignore index d0a65ef..1a9e589 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /Cargo.lock **/*.rs.bk +rusty-tags.emacs diff --git a/Cargo.toml b/Cargo.toml index cb646a4..4449903 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["geo", "geospatial", "kml"] exclude = [".github/*"] [dependencies] -quick-xml = "0.28" +quick-xml = "0.31" num-traits = "0.2" thiserror = "1.0" geo-types = { version = ">=0.6, <0.8", optional = true } diff --git a/src/errors.rs b/src/errors.rs index ad2271d..679d977 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -5,7 +5,7 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum Error { #[error("Invalid input supplied for XML")] - InvalidInput, + InvalidInput(String), #[error("Encountered malformed XML: {0}")] MalformedXml(#[from] quick_xml::Error), #[error("Invalid XML event: {0}")] diff --git a/src/kmz_reader.rs b/src/kmz_reader.rs index 34ede0f..47aabfb 100644 --- a/src/kmz_reader.rs +++ b/src/kmz_reader.rs @@ -36,7 +36,9 @@ where // Should parse the first file with a KML extension for i in 0..archive.len() { - let mut kml_file = archive.by_index(i).map_err(|_| Error::InvalidInput)?; + let mut kml_file = archive + .by_index(i) + .map_err(|e| Error::InvalidInput(format!("{e:?}")))?; if !kml_file.name().to_ascii_lowercase().ends_with(".kml") { continue; } @@ -45,7 +47,9 @@ where return Ok(KmlReader::from_reader(Cursor::new(buf))); } - Err(Error::InvalidInput) + Err(Error::InvalidInput( + "Archive contains no elements".to_string(), + )) } } diff --git a/src/reader.rs b/src/reader.rs index 49ce57a..4f5e4b3 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -194,7 +194,8 @@ where }, Event::Decl(_) | Event::CData(_) | Event::Empty(_) | Event::Text(_) => {} Event::Eof => break, - _ => return Err(Error::InvalidInput), + Event::Comment(_) => {} + x => return Err(Error::InvalidInput(format!("{:?}", x))), }; } @@ -812,7 +813,9 @@ where simple_array_data.name = name; simple_array_data.attrs = attrs; } else { - return Err(Error::InvalidInput); + return Err(Error::InvalidInput( + "Required \"name\" attribute not present".to_string(), + )); } loop { @@ -848,7 +851,9 @@ where attrs, }) } else { - Err(Error::InvalidInput) + Err(Error::InvalidInput( + "Required \"name\" attribute not present".to_string(), + )) } } @@ -1344,7 +1349,7 @@ mod tests { #[test] fn test_read_schema_data() { - let kml_str = r###" + let kml_str = r##" Pi in the sky 3.14159 @@ -1356,7 +1361,7 @@ mod tests { 181 - "###; + "##; let a: Kml = kml_str.parse().unwrap(); assert_eq!( @@ -1684,4 +1689,14 @@ mod tests { Kml::KmlDocument(_) )) } + + #[test] + fn test_parse_style_merging() { + let kml_str = include_str!("../tests/fixtures/style-merging.kml"); + + assert!(matches!( + Kml::::from_str(kml_str).unwrap(), + Kml::KmlDocument(_) + )); + } } diff --git a/tests/fixtures/style-merging.kml b/tests/fixtures/style-merging.kml new file mode 100644 index 0000000..6f5c30d --- /dev/null +++ b/tests/fixtures/style-merging.kml @@ -0,0 +1,126 @@ + + + + 1 + + + + Wideawake field + 1 + + Airport + Is this the world's most remote airfield? + #globalStyles + + + + -14.392095,-7.967700,0 + + + + runway + #globalStyles + + + 1 + -14.405821,-7.963539 -14.381448,-7.975707 + + + + apron + #globalStyles + + + 1 + + + + -14.405214,-7.968981 + -14.402106,-7.970539 + -14.399850,-7.968762 + -14.399670,-7.968411 + -14.403875,-7.966311 + -14.405214,-7.968981 + + + + + + + + diff --git a/tests/test_roundtrip.rs b/tests/test_roundtrip.rs index 695e04b..48fcbd8 100644 --- a/tests/test_roundtrip.rs +++ b/tests/test_roundtrip.rs @@ -30,6 +30,7 @@ mod roundtrip_tests { test_polygon: "polygon.kml", test_sample: "sample.kml", test_countries: "countries.kml", + test_style_merging: "style-merging.kml", } // Confirms that parsing from KML and writing back doesn't drop any currently tracked data