Skip to main content

lenso_capability_http_endpoint/
generated.rs

1// @generated by lenso-contract-codegen; do not edit.
2use std::{fmt, rc::Rc};
3use futures::future::LocalBoxFuture;
4use lenso_kernel::{InvocationContext, ModuleDependencies, NativeRequestEndpoint, NativeRequestFuture, NativeRequestHandle, RequestCapability, RuntimeFailure};
5
6pub const CAPABILITY_ID: &str = "lenso.http.endpoint@1";
7pub const DESCRIPTOR_VERSION: &str = "1.1.0";
8pub const PORTABLE: bool = true;
9pub const CROSS_LANE_TRANSFER: bool = true;
10pub const ENDPOINT_CAPABILITY_ID: &str = CAPABILITY_ID;
11pub const ENDPOINT_DESCRIPTOR_VERSION: &str = DESCRIPTOR_VERSION;
12
13pub const DESCRIBE_OPERATION: &str = "describe";
14pub const HANDLE_OPERATION: &str = "handle";
15
16pub use lenso_contract_runtime::{Bytes, UnknownDomainError};
17use lenso_contract_runtime::{decode_portable_json, encode_portable_json};
18
19#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
20pub struct DescribeRequest {
21
22}
23
24#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
25pub struct DescribeResponse {
26    #[serde(rename = "routes")]
27    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
28    pub routes: Vec<DescribeResponseRoutesItem>,
29}
30
31#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
32pub struct DescribeResponseRoutesItem {
33    #[serde(rename = "method")]
34    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
35    pub method: String,
36    #[serde(rename = "openapi")]
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub openapi: Option<std::collections::BTreeMap<String, serde_json::Value>>,
39    #[serde(rename = "path")]
40    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
41    pub path: String,
42    #[serde(rename = "route_id")]
43    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
44    pub route_id: String,
45}
46
47#[derive(Clone, Debug, PartialEq)]
48pub enum DescribeError {
49    InvalidConfiguration,
50    Unknown(UnknownDomainError),
51}
52
53#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
54pub struct HandleRequest {
55    #[serde(rename = "body")]
56    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
57    pub body: Bytes,
58    #[serde(rename = "credential")]
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub credential: Option<HandleRequestCredential>,
61    #[serde(rename = "headers")]
62    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
63    pub headers: Vec<HandleRequestHeadersItem>,
64    #[serde(rename = "method")]
65    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
66    pub method: String,
67    #[serde(rename = "path")]
68    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
69    pub path: String,
70    #[serde(rename = "path_parameters")]
71    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
72    pub path_parameters: Vec<HandleRequestPathParametersItem>,
73    #[serde(rename = "query")]
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub query: Option<String>,
76    #[serde(rename = "request_id")]
77    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
78    pub request_id: String,
79    #[serde(rename = "route_id")]
80    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
81    pub route_id: String,
82}
83
84#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
85pub struct HandleRequestCredential {
86    #[serde(rename = "scheme")]
87    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
88    pub scheme: String,
89    #[serde(rename = "value")]
90    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
91    pub value: String,
92}
93
94#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
95pub struct HandleRequestHeadersItem {
96    #[serde(rename = "name")]
97    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
98    pub name: String,
99    #[serde(rename = "value")]
100    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
101    pub value: String,
102}
103
104#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
105pub struct HandleRequestPathParametersItem {
106    #[serde(rename = "name")]
107    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
108    pub name: String,
109    #[serde(rename = "value")]
110    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
111    pub value: String,
112}
113
114#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
115pub struct HandleResponse {
116    #[serde(rename = "body")]
117    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
118    pub body: Bytes,
119    #[serde(rename = "headers")]
120    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
121    pub headers: Vec<HandleResponseHeadersItem>,
122    #[serde(rename = "status")]
123    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
124    pub status: i64,
125}
126
127#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
128pub struct HandleResponseHeadersItem {
129    #[serde(rename = "name")]
130    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
131    pub name: String,
132    #[serde(rename = "value")]
133    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
134    pub value: String,
135}
136
137#[derive(Clone, Debug, PartialEq)]
138pub enum HandleError {
139    Rejected,
140    Unknown(UnknownDomainError),
141}
142
143#[derive(Debug)]
144pub struct EndpointDescribe;
145impl RequestCapability for EndpointDescribe {
146    type Request = DescribeRequest;
147    type Response = DescribeResponse;
148    type DomainError = DescribeError;
149    const ID: &'static str = CAPABILITY_ID;
150    const DESCRIPTOR_VERSION: &'static str = DESCRIPTOR_VERSION;
151
152    fn invoke_native(endpoint: &dyn NativeRequestEndpoint, operation: &str, request: Self::Request, context: InvocationContext) -> NativeRequestFuture<Self> {
153        if operation != DESCRIBE_OPERATION {
154            return lenso_kernel::invoke_typed_or_erased_native_request::<Self>(endpoint, operation, request, context);
155        }
156        let Some(typed_endpoint) = endpoint
157            .typed_endpoint()
158            .and_then(|endpoint| endpoint.downcast_ref::<EndpointRequestEndpoint>())
159        else {
160            return lenso_kernel::invoke_typed_or_erased_native_request::<Self>(endpoint, operation, request, context);
161        };
162        Rc::clone(&typed_endpoint.provider).describe(context, request)
163    }
164}
165
166#[derive(Debug)]
167pub struct EndpointHandle;
168impl RequestCapability for EndpointHandle {
169    type Request = HandleRequest;
170    type Response = HandleResponse;
171    type DomainError = HandleError;
172    const ID: &'static str = CAPABILITY_ID;
173    const DESCRIPTOR_VERSION: &'static str = DESCRIPTOR_VERSION;
174
175    fn invoke_native(endpoint: &dyn NativeRequestEndpoint, operation: &str, request: Self::Request, context: InvocationContext) -> NativeRequestFuture<Self> {
176        if operation != HANDLE_OPERATION {
177            return lenso_kernel::invoke_typed_or_erased_native_request::<Self>(endpoint, operation, request, context);
178        }
179        let Some(typed_endpoint) = endpoint
180            .typed_endpoint()
181            .and_then(|endpoint| endpoint.downcast_ref::<EndpointRequestEndpoint>())
182        else {
183            return lenso_kernel::invoke_typed_or_erased_native_request::<Self>(endpoint, operation, request, context);
184        };
185        Rc::clone(&typed_endpoint.provider).handle(context, request)
186    }
187}
188
189impl serde::Serialize for DescribeError {
190    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
191    where
192        S: serde::Serializer,
193    {
194        use serde::ser::SerializeMap;
195        match self {
196            Self::InvalidConfiguration => serializer.serialize_str("invalid_configuration"),
197            Self::Unknown(value) => {
198                let mut map = serializer.serialize_map(Some(1 + usize::from(value.payload.is_some()) + value.extra.len()))?;
199                map.serialize_entry("code", &value.code)?;
200                if let Some(payload) = &value.payload {
201                    map.serialize_entry("payload", payload)?;
202                }
203                for (key, extra) in &value.extra {
204                    map.serialize_entry(key, extra)?;
205                }
206                map.end()
207            },
208        }
209    }
210}
211
212impl<'de> serde::Deserialize<'de> for DescribeError {
213    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
214    where
215        D: serde::Deserializer<'de>,
216    {
217        let value = <serde_json::Value as serde::Deserialize>::deserialize(deserializer)?;
218        match value {
219            serde_json::Value::String(code) => match code.as_str() {
220                "invalid_configuration" => Ok(Self::InvalidConfiguration),
221                _ => Ok(Self::Unknown(UnknownDomainError { code, payload: None, extra: std::collections::BTreeMap::new() })),
222            },
223            serde_json::Value::Object(mut object) => {
224                let Some(code) = object.remove("code").and_then(|value| value.as_str().map(ToOwned::to_owned)) else {
225                    return Err(serde::de::Error::custom("Domain Error object is missing a string code"));
226                };
227                let payload = object.remove("payload");
228                let extra = object.into_iter().collect::<std::collections::BTreeMap<_, _>>();
229                Ok(Self::Unknown(UnknownDomainError { code, payload, extra }))
230            }
231            other => Err(serde::de::Error::custom(format!("Domain Error must be a string or object, got {other}"))),
232        }
233    }
234}
235
236impl serde::Serialize for HandleError {
237    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
238    where
239        S: serde::Serializer,
240    {
241        use serde::ser::SerializeMap;
242        match self {
243            Self::Rejected => serializer.serialize_str("rejected"),
244            Self::Unknown(value) => {
245                let mut map = serializer.serialize_map(Some(1 + usize::from(value.payload.is_some()) + value.extra.len()))?;
246                map.serialize_entry("code", &value.code)?;
247                if let Some(payload) = &value.payload {
248                    map.serialize_entry("payload", payload)?;
249                }
250                for (key, extra) in &value.extra {
251                    map.serialize_entry(key, extra)?;
252                }
253                map.end()
254            },
255        }
256    }
257}
258
259impl<'de> serde::Deserialize<'de> for HandleError {
260    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
261    where
262        D: serde::Deserializer<'de>,
263    {
264        let value = <serde_json::Value as serde::Deserialize>::deserialize(deserializer)?;
265        match value {
266            serde_json::Value::String(code) => match code.as_str() {
267                "rejected" => Ok(Self::Rejected),
268                _ => Ok(Self::Unknown(UnknownDomainError { code, payload: None, extra: std::collections::BTreeMap::new() })),
269            },
270            serde_json::Value::Object(mut object) => {
271                let Some(code) = object.remove("code").and_then(|value| value.as_str().map(ToOwned::to_owned)) else {
272                    return Err(serde::de::Error::custom("Domain Error object is missing a string code"));
273                };
274                let payload = object.remove("payload");
275                let extra = object.into_iter().collect::<std::collections::BTreeMap<_, _>>();
276                Ok(Self::Unknown(UnknownDomainError { code, payload, extra }))
277            }
278            other => Err(serde::de::Error::custom(format!("Domain Error must be a string or object, got {other}"))),
279        }
280    }
281}
282
283pub fn encode_describe_request(value: &DescribeRequest) -> Result<String, serde_json::Error> { encode_portable_json(value) }
284pub fn decode_describe_request(wire: &str) -> Result<DescribeRequest, serde_json::Error> { decode_portable_json(wire) }
285pub fn encode_describe_response(value: &DescribeResponse) -> Result<String, serde_json::Error> { encode_portable_json(value) }
286pub fn decode_describe_response(wire: &str) -> Result<DescribeResponse, serde_json::Error> { decode_portable_json(wire) }
287pub fn encode_describe_error(value: &DescribeError) -> Result<String, serde_json::Error> { encode_portable_json(value) }
288pub fn decode_describe_error(wire: &str) -> Result<DescribeError, serde_json::Error> { decode_portable_json(wire) }
289
290pub fn encode_handle_request(value: &HandleRequest) -> Result<String, serde_json::Error> { encode_portable_json(value) }
291pub fn decode_handle_request(wire: &str) -> Result<HandleRequest, serde_json::Error> { decode_portable_json(wire) }
292pub fn encode_handle_response(value: &HandleResponse) -> Result<String, serde_json::Error> { encode_portable_json(value) }
293pub fn decode_handle_response(wire: &str) -> Result<HandleResponse, serde_json::Error> { decode_portable_json(wire) }
294pub fn encode_handle_error(value: &HandleError) -> Result<String, serde_json::Error> { encode_portable_json(value) }
295pub fn decode_handle_error(wire: &str) -> Result<HandleError, serde_json::Error> { decode_portable_json(wire) }
296
297pub trait EndpointProvider: fmt::Debug + 'static {
298    fn describe(&self, context: InvocationContext, request: DescribeRequest) -> NativeRequestFuture<EndpointDescribe>;
299    fn handle(&self, context: InvocationContext, request: HandleRequest) -> NativeRequestFuture<EndpointHandle>;
300}
301
302#[derive(Debug)]
303struct EndpointRequestEndpoint { provider: Rc<dyn EndpointProvider> }
304
305#[derive(Debug)]
306pub struct EndpointEndpoint<P: EndpointProvider> { provider: Rc<P>, request_endpoint: EndpointRequestEndpoint }
307impl<P: EndpointProvider> EndpointEndpoint<P> {
308    pub fn new(provider: P) -> Self {
309        let provider = Rc::new(provider);
310        let request_provider: Rc<dyn EndpointProvider> = provider.clone();
311        Self { provider, request_endpoint: EndpointRequestEndpoint { provider: request_provider } }
312    }
313}
314
315impl<P: EndpointProvider> NativeRequestEndpoint for EndpointEndpoint<P> {
316    fn capability_id(&self) -> &'static str { CAPABILITY_ID }
317    fn descriptor_version(&self) -> &'static str { DESCRIPTOR_VERSION }
318    fn operations(&self) -> &'static [&'static str] { &[
319        DESCRIBE_OPERATION,
320        HANDLE_OPERATION,
321    ] }
322    fn typed_endpoint(&self) -> Option<&dyn std::any::Any> { Some(&self.request_endpoint) }
323    fn invoke(&self, operation: &str, request: Box<dyn std::any::Any>, context: InvocationContext) -> LocalBoxFuture<'static, Result<Result<Box<dyn std::any::Any>, Box<dyn std::any::Any>>, RuntimeFailure>> {
324        match operation {
325            DESCRIBE_OPERATION => {
326                let Ok(request) = request.downcast::<DescribeRequest>() else {
327                    return Box::pin(futures::future::ready(Err(RuntimeFailure::ProtocolViolation { capability: CAPABILITY_ID })));
328                };
329                let invocation = Rc::clone(&self.provider).describe(context, *request);
330                Box::pin(async move {
331                    invocation.await.map(|result| {
332                        result
333                            .map(|value| Box::new(value) as Box<dyn std::any::Any>)
334                            .map_err(|error| Box::new(error) as Box<dyn std::any::Any>)
335                    })
336                })
337            },
338            HANDLE_OPERATION => {
339                let Ok(request) = request.downcast::<HandleRequest>() else {
340                    return Box::pin(futures::future::ready(Err(RuntimeFailure::ProtocolViolation { capability: CAPABILITY_ID })));
341                };
342                let invocation = Rc::clone(&self.provider).handle(context, *request);
343                Box::pin(async move {
344                    invocation.await.map(|result| {
345                        result
346                            .map(|value| Box::new(value) as Box<dyn std::any::Any>)
347                            .map_err(|error| Box::new(error) as Box<dyn std::any::Any>)
348                    })
349                })
350            }
351            _ => Box::pin(futures::future::ready(Err(RuntimeFailure::UnknownOperation { capability: CAPABILITY_ID, operation: operation.to_owned() }))),
352        }
353    }
354}
355
356#[derive(Debug)]
357pub struct EndpointClient {
358    describe: NativeRequestHandle<EndpointDescribe>,
359    handle: NativeRequestHandle<EndpointHandle>,
360}
361impl EndpointClient {
362    pub fn from_dependencies(dependencies: &ModuleDependencies) -> Result<Self, RuntimeFailure> {
363        Ok(Self {
364            describe: dependencies.one::<EndpointDescribe>()?,
365            handle: dependencies.one::<EndpointHandle>()?,
366        })
367    }
368
369    pub async fn describe(&self, request: DescribeRequest) -> Result<DescribeResponse, EndpointDescribeInvocationError> {
370        self.describe.invoke(DESCRIBE_OPERATION, request).await
371            .map_err(EndpointDescribeInvocationError::Runtime)?
372            .map_err(EndpointDescribeInvocationError::Domain)
373    }
374
375    pub async fn describe_with_context(&self, context: InvocationContext, request: DescribeRequest) -> Result<DescribeResponse, EndpointDescribeInvocationError> {
376        self.describe.invoke_with_context(DESCRIBE_OPERATION, context, request).await
377            .map_err(EndpointDescribeInvocationError::Runtime)?
378            .map_err(EndpointDescribeInvocationError::Domain)
379    }
380
381    pub async fn handle(&self, request: HandleRequest) -> Result<HandleResponse, EndpointHandleInvocationError> {
382        self.handle.invoke(HANDLE_OPERATION, request).await
383            .map_err(EndpointHandleInvocationError::Runtime)?
384            .map_err(EndpointHandleInvocationError::Domain)
385    }
386
387    pub async fn handle_with_context(&self, context: InvocationContext, request: HandleRequest) -> Result<HandleResponse, EndpointHandleInvocationError> {
388        self.handle.invoke_with_context(HANDLE_OPERATION, context, request).await
389            .map_err(EndpointHandleInvocationError::Runtime)?
390            .map_err(EndpointHandleInvocationError::Domain)
391    }
392}
393
394#[derive(Clone, Debug, PartialEq)]
395pub enum EndpointDescribeInvocationError {
396    Domain(DescribeError),
397    Runtime(RuntimeFailure),
398}
399#[derive(Clone, Debug, PartialEq)]
400pub enum EndpointHandleInvocationError {
401    Domain(HandleError),
402    Runtime(RuntimeFailure),
403}