use crate::{Feature, FeatureCollection, GeoJson, Geometry, Value};
use elicitation::contracts::Established;
use elicitation::{ElicitPlugin, Prop, VerifiedWorkflow, elicit_tool};
use rmcp::ErrorData;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use tracing::instrument;
use super::json_result;
#[derive(Prop)]
pub struct GeoJsonConverted;
impl VerifiedWorkflow for GeoJsonConverted {}
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GeometryFromGeoGeometryParams {
pub geometry: elicit_geo_types::Geometry,
}
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ValueFromGeoGeometryParams {
pub geometry: elicit_geo_types::Geometry,
}
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct FeatureCollectionFromGeoGeometryCollectionParams {
pub collection: elicit_geo_types::GeometryCollection,
}
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GeoGeometryFromGeoJsonParams {
pub geojson: GeoJson,
}
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GeoGeometryFromGeometryParams {
pub geometry: Geometry,
}
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GeoGeometryFromValueParams {
pub value: Value,
}
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GeoGeometryFromFeatureParams {
pub feature: Feature,
}
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GeoGeometryFromFeatureCollectionParams {
pub collection: FeatureCollection,
}
#[elicit_tool(
plugin = "geojson_conversion",
name = "geometry_from_geo_geometry",
description = "Convert an elicit_geo_types geometry wrapper to a GeoJSON geometry object. Establishes: GeoJsonConverted."
)]
#[instrument]
async fn geometry_from_geo_geometry(
p: GeometryFromGeoGeometryParams,
) -> Result<rmcp::model::CallToolResult, ErrorData> {
let geometry = Geometry::from(&p.geometry);
let _proof = Established::<GeoJsonConverted>::assert();
json_result(&geometry)
}
#[elicit_tool(
plugin = "geojson_conversion",
name = "value_from_geo_geometry",
description = "Convert an elicit_geo_types geometry wrapper to a GeoJSON geometry value. Establishes: GeoJsonConverted."
)]
#[instrument]
async fn value_from_geo_geometry(
p: ValueFromGeoGeometryParams,
) -> Result<rmcp::model::CallToolResult, ErrorData> {
let value = Value::from(&p.geometry);
let _proof = Established::<GeoJsonConverted>::assert();
json_result(&value)
}
#[elicit_tool(
plugin = "geojson_conversion",
name = "feature_collection_from_geo_geometry_collection",
description = "Convert an elicit_geo_types geometry collection wrapper to a GeoJSON feature collection. Establishes: GeoJsonConverted."
)]
#[instrument]
async fn feature_collection_from_geo_geometry_collection(
p: FeatureCollectionFromGeoGeometryCollectionParams,
) -> Result<rmcp::model::CallToolResult, ErrorData> {
let collection = FeatureCollection::from(&p.collection);
let _proof = Established::<GeoJsonConverted>::assert();
json_result(&collection)
}
#[elicit_tool(
plugin = "geojson_conversion",
name = "geo_geometry_from_geojson",
description = "Convert a GeoJSON document to an elicit_geo_types geometry wrapper. Establishes: GeoJsonConverted."
)]
#[instrument]
async fn geo_geometry_from_geojson(
p: GeoGeometryFromGeoJsonParams,
) -> Result<rmcp::model::CallToolResult, ErrorData> {
let geometry = elicit_geo_types::Geometry::try_from(p.geojson)
.map_err(|error| ErrorData::invalid_params(error.to_string(), None))?;
let _proof = Established::<GeoJsonConverted>::assert();
json_result(&geometry)
}
#[elicit_tool(
plugin = "geojson_conversion",
name = "geo_geometry_from_geometry",
description = "Convert a GeoJSON geometry object to an elicit_geo_types geometry wrapper. Establishes: GeoJsonConverted."
)]
#[instrument]
async fn geo_geometry_from_geometry(
p: GeoGeometryFromGeometryParams,
) -> Result<rmcp::model::CallToolResult, ErrorData> {
let geometry = elicit_geo_types::Geometry::try_from(p.geometry)
.map_err(|error| ErrorData::invalid_params(error.to_string(), None))?;
let _proof = Established::<GeoJsonConverted>::assert();
json_result(&geometry)
}
#[elicit_tool(
plugin = "geojson_conversion",
name = "geo_geometry_from_value",
description = "Convert a GeoJSON geometry value to an elicit_geo_types geometry wrapper. Establishes: GeoJsonConverted."
)]
#[instrument]
async fn geo_geometry_from_value(
p: GeoGeometryFromValueParams,
) -> Result<rmcp::model::CallToolResult, ErrorData> {
let geometry = elicit_geo_types::Geometry::try_from(p.value)
.map_err(|error| ErrorData::invalid_params(error.to_string(), None))?;
let _proof = Established::<GeoJsonConverted>::assert();
json_result(&geometry)
}
#[elicit_tool(
plugin = "geojson_conversion",
name = "geo_geometry_from_feature",
description = "Convert a GeoJSON feature to an elicit_geo_types geometry wrapper. Establishes: GeoJsonConverted."
)]
#[instrument]
async fn geo_geometry_from_feature(
p: GeoGeometryFromFeatureParams,
) -> Result<rmcp::model::CallToolResult, ErrorData> {
let geometry = elicit_geo_types::Geometry::try_from(p.feature)
.map_err(|error| ErrorData::invalid_params(error.to_string(), None))?;
let _proof = Established::<GeoJsonConverted>::assert();
json_result(&geometry)
}
#[elicit_tool(
plugin = "geojson_conversion",
name = "geo_geometry_from_feature_collection",
description = "Convert a GeoJSON feature collection to an elicit_geo_types geometry wrapper. Establishes: GeoJsonConverted."
)]
#[instrument]
async fn geo_geometry_from_feature_collection(
p: GeoGeometryFromFeatureCollectionParams,
) -> Result<rmcp::model::CallToolResult, ErrorData> {
let geometry = elicit_geo_types::Geometry::try_from(p.collection)
.map_err(|error| ErrorData::invalid_params(error.to_string(), None))?;
let _proof = Established::<GeoJsonConverted>::assert();
json_result(&geometry)
}
#[derive(Debug, ElicitPlugin)]
#[plugin(name = "geojson_conversion")]
pub struct GeoJsonConversionPlugin;
impl GeoJsonConversionPlugin {
#[instrument]
pub fn new() -> Self {
Self
}
}
impl Default for GeoJsonConversionPlugin {
fn default() -> Self {
Self::new()
}
}