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