geoparquet_validator/
lib.rs1pub mod checks;
22pub mod corpus;
23pub mod crs;
24pub mod source;
25pub mod spatial;
26pub mod verify;
27pub mod wkb;
28
29#[cfg(feature = "capi")]
30pub mod capi;
31#[cfg(feature = "cli")]
32pub mod cli;
33#[cfg(feature = "python")]
34mod python;
35#[cfg(feature = "wasm")]
36pub mod wasm;
37
38use checks::{Options, Report, Schemas};
39
40pub fn validate(target: &str, max_rows: Option<usize>) -> anyhow::Result<Report> {
44 let schemas = Schemas::load()?;
45 let options = Options { max_rows };
46 #[cfg(feature = "remote")]
47 if source::is_remote(target) {
48 let url = url::Url::parse(target)?;
49 let opts = source::RemoteOptions {
50 s3_region: None,
51 extra: Vec::new(),
52 };
53 let src = source::open_remote(&url, &opts)?;
54 return checks::run(&src, &schemas, &options);
55 }
56 let src = source::Local(std::path::PathBuf::from(target));
57 checks::run(&src, &schemas, &options)
58}
59
60pub fn validate_bytes(
62 name: &str,
63 bytes: Vec<u8>,
64 max_rows: Option<usize>,
65) -> anyhow::Result<Report> {
66 let schemas = Schemas::load()?;
67 let src = source::InMemory {
68 name: name.to_string(),
69 bytes: bytes::Bytes::from(bytes),
70 };
71 checks::run(&src, &schemas, &Options { max_rows })
72}
73
74#[cfg(test)]
75mod tests {
76 #[test]
77 fn report_matches_its_schema() {
78 let schema: serde_json::Value =
79 serde_json::from_str(include_str!("../schemas/report.schema.json")).unwrap();
80 let validator = jsonschema::validator_for(&schema).unwrap();
81 let path = "corpus/data/bbox/bbox-present.parquet";
83 if !std::path::Path::new(path).exists() {
84 eprintln!("skipped: {path} not present");
85 return;
86 }
87 let report = super::validate(path, None).unwrap();
88 let value = serde_json::to_value(&report).unwrap();
89 let errors: Vec<String> = validator
90 .iter_errors(&value)
91 .map(|e| e.to_string())
92 .collect();
93 assert!(errors.is_empty(), "{errors:?}");
94 assert_eq!(value["report_version"], 1);
95 }
96}