From 78b30fc4bad6c18a61dccf32f5c4b9f072ba41fa Mon Sep 17 00:00:00 2001 From: rzmk <30333942+rzmk@users.noreply.github.com> Date: Wed, 13 May 2026 18:31:45 -0400 Subject: [PATCH] feat: construct about value, use title for name, error handling --- src/jsonld.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++------- src/main.rs | 10 +++++++-- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/jsonld.rs b/src/jsonld.rs index 2efa904..55795dd 100644 --- a/src/jsonld.rs +++ b/src/jsonld.rs @@ -1,10 +1,11 @@ +use anyhow::{Result, bail}; use serde_json::json; pub fn construct_dataset_jsonld_from_metadata( dataset_metadata: serde_json::Value, -) -> serde_json::Value { +) -> Result { let dataset_id = dataset_metadata.get("id").unwrap().as_str().unwrap(); - let dataset_name = dataset_metadata.get("name").unwrap().as_str().unwrap(); + let dataset_title = dataset_metadata.get("title").unwrap().as_str().unwrap(); let organization_name = dataset_metadata .get("organization") .unwrap() @@ -13,8 +14,45 @@ pub fn construct_dataset_jsonld_from_metadata( // TODO: Align and include Geoconnex PIDs for reference feature categories to extract PIDs from them // Then also convert spatial_full FeatureCollection to Multipolygon if needed for gsp:hasGeometry when there are // also non-reference feature polygons - // if let Some(spatial_full) = dataset_metadata.get("spatial_full") {} - let jsonld = json!({ + let mut about = vec![]; + if let Some(spatial_full) = dataset_metadata.get("spatial_full") { + let Some(spatial_full_str) = spatial_full.as_str() else { + bail!("Could not parse spatial_full as string."); + }; + if !spatial_full_str.is_empty() { + let Ok(spatial_full_json) = serde_json::from_str::(spatial_full_str) + else { + bail!( + "Error while attempting to deserialize spatial_full string to serde_json::Value." + ); + }; + let Some(features_value) = spatial_full_json.get("features") else { + bail!("Error while attempting to get value of features from spatial_full GeoJSON."); + }; + let Some(features) = features_value.as_array() else { + bail!( + "Eerror while attempting to take features value as array from spatial_full GeoJSON." + ); + }; + for feature in features { + let Some(properties) = feature.get("properties") else { + bail!( + "Error while attempting to get properties from features from spatial_full GeoJSON." + ); + }; + if let Some(pid) = properties.get("pid") { + let Some(pid_string) = pid.as_str() else { + bail!("Error while attempting to convert PID as str from &Value."); + }; + about.push(json!({ + "@id": pid_string, + "@type": "Place" + })); + } + } + } + } + let mut jsonld = json!({ "@context": { "@vocab": "https://schema.org/", "gsp": "http://www.opengis.net/ont/geosparql#", @@ -22,11 +60,17 @@ pub fn construct_dataset_jsonld_from_metadata( "@type": "Dataset", // TODO: Customize namespace based on CKAN instance being used "@id": format!("https://geoconnex.us/nmwdh/ckan-datasets/{dataset_id}"), - "name": dataset_name, + "name": dataset_title, "provider": { "@type": "Organization", "name": organization_name - } + }, + // TODO: Customize CKAN instance URL based on CKAN instance being used + "url": format!("http://localhost:5000/dataset/{dataset_id}") }); - jsonld + let jsonld_map = jsonld.as_object_mut().unwrap(); + if about.len() > 0 { + jsonld_map.insert("about".to_string(), serde_json::to_value(about).unwrap()); + } + Ok(serde_json::to_value(jsonld_map).unwrap()) } diff --git a/src/main.rs b/src/main.rs index 686a6fc..96cc78d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,8 +61,14 @@ async fn main() -> Result<()> { ); }; // 2. Construct JSON-LD based on the data from /package_show - let jsonld = - construct_dataset_jsonld_from_metadata(dataset_metadata.to_owned()); + let jsonld = match construct_dataset_jsonld_from_metadata( + dataset_metadata.to_owned(), + ) { + Ok(j) => j, + Err(e) => bail!( + "Error while attempting to construct JSON-LD from dataset's metadata: {e}" + ), + }; // 3. Validate the JSON-LD against the dataset JSON schema if jsonschema::validate(&get_dataset_schema(), &jsonld).is_ok() { // 4. Print the JSON-LD on a new line to stdout