ogcapi_processes/
greeter.rs1use std::collections::HashMap;
2
3use anyhow::Result;
4use schemars::{JsonSchema, schema_for};
5use serde::Deserialize;
6
7use ogcapi_types::{
8 common::Exception,
9 processes::{
10 Execute, Format, InlineOrRefData, Input, InputValueNoObject, Output, Process,
11 TransmissionMode,
12 },
13};
14
15use crate::{ProcessResponseBody, Processor};
16
17#[derive(Clone)]
29pub struct Greeter;
30
31#[derive(Deserialize, Debug, JsonSchema)]
33pub struct GreeterInputs {
34 pub name: String,
36}
37
38impl GreeterInputs {
39 pub fn execute_input(&self) -> HashMap<String, Input> {
40 HashMap::from([(
41 "name".to_string(),
42 Input::InlineOrRefData(InlineOrRefData::InputValueNoObject(
43 InputValueNoObject::String(self.name.to_owned()),
44 )),
45 )])
46 }
47}
48
49#[derive(Clone, Debug, JsonSchema)]
51pub struct GreeterOutputs {
52 pub greeting: String,
53}
54
55impl GreeterOutputs {
56 pub fn execute_output() -> HashMap<String, Output> {
57 HashMap::from([(
58 "greeting".to_string(),
59 Output {
60 format: Some(Format {
61 media_type: Some("text/plain".to_string()),
62 encoding: Some("utf8".to_string()),
63 schema: None,
64 }),
65 transmission_mode: TransmissionMode::Value,
66 },
67 )])
68 }
69}
70
71impl TryFrom<ProcessResponseBody> for GreeterOutputs {
72 type Error = Exception;
73
74 fn try_from(value: ProcessResponseBody) -> Result<Self, Self::Error> {
75 if let ProcessResponseBody::Requested(buf) = value {
76 Ok(GreeterOutputs {
77 greeting: String::from_utf8(buf).unwrap(),
78 })
79 } else {
80 Err(Exception::new("500"))
81 }
82 }
83}
84
85#[async_trait::async_trait]
86impl Processor for Greeter {
87 fn id(&self) -> &'static str {
88 "greet"
89 }
90
91 fn version(&self) -> &'static str {
92 "0.1.0"
93 }
94
95 fn process(&self) -> Result<Process> {
96 Process::try_new(
97 self.id(),
98 self.version(),
99 &schema_for!(GreeterInputs).schema,
100 &schema_for!(GreeterOutputs).schema,
101 )
102 .map_err(Into::into)
103 }
104
105 async fn execute(&self, execute: Execute) -> Result<ProcessResponseBody> {
106 let value = serde_json::to_value(execute.inputs).unwrap();
107 let inputs: GreeterInputs = serde_json::from_value(value).unwrap();
108 Ok(ProcessResponseBody::Requested(
109 format!("Hello, {}!\n", inputs.name).as_bytes().to_owned(),
110 ))
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use ogcapi_types::processes::Execute;
117
118 use crate::{
119 Processor,
120 greeter::{Greeter, GreeterInputs, GreeterOutputs},
121 };
122
123 #[tokio::test]
124 async fn test_greeter() {
125 let greeter = Greeter;
126 assert_eq!(greeter.id(), "greet");
127
128 println!(
129 "Process:\n{}",
130 serde_json::to_string_pretty(&greeter.process().unwrap()).unwrap()
131 );
132
133 let input = GreeterInputs {
134 name: "Greeter".to_string(),
135 };
136
137 let execute = Execute {
138 inputs: input.execute_input(),
139 outputs: GreeterOutputs::execute_output(),
140 ..Default::default()
141 };
142
143 let output: GreeterOutputs = greeter.execute(execute).await.unwrap().try_into().unwrap();
144 assert_eq!(output.greeting, "Hello, Greeter!\n");
145 }
146}