surrealdb/api/method/
content.rs1use crate::api::conn::Method;
2use crate::api::conn::Param;
3use crate::api::opt::Range;
4use crate::api::opt::Resource;
5use crate::api::Connection;
6use crate::api::Result;
7use crate::method::OnceLockExt;
8use crate::sql::to_value;
9use crate::sql::Id;
10use crate::sql::Value;
11use crate::Surreal;
12use serde::de::DeserializeOwned;
13use serde::Serialize;
14use std::borrow::Cow;
15use std::future::Future;
16use std::future::IntoFuture;
17use std::marker::PhantomData;
18use std::pin::Pin;
19
20#[derive(Debug)]
24#[must_use = "futures do nothing unless you `.await` or poll them"]
25pub struct Content<'r, C: Connection, D, R> {
26 pub(super) client: Cow<'r, Surreal<C>>,
27 pub(super) method: Method,
28 pub(super) resource: Result<Resource>,
29 pub(super) range: Option<Range<Id>>,
30 pub(super) content: D,
31 pub(super) response_type: PhantomData<R>,
32}
33
34impl<C, D, R> Content<'_, C, D, R>
35where
36 C: Connection,
37{
38 pub fn into_owned(self) -> Content<'static, C, D, R> {
40 Content {
41 client: Cow::Owned(self.client.into_owned()),
42 ..self
43 }
44 }
45}
46
47macro_rules! into_future {
48 ($method:ident) => {
49 fn into_future(self) -> Self::IntoFuture {
50 let Content {
51 client,
52 method,
53 resource,
54 range,
55 content,
56 ..
57 } = self;
58 let content = to_value(content);
59 Box::pin(async move {
60 let param = match range {
61 Some(range) => resource?.with_range(range)?.into(),
62 None => resource?.into(),
63 };
64 let mut conn = Client::new(method);
65 let params = match content? {
66 Value::None | Value::Null => vec![param],
67 content => vec![param, content],
68 };
69 conn.$method(client.router.extract()?, Param::new(params)).await
70 })
71 }
72 };
73}
74
75impl<'r, Client, D> IntoFuture for Content<'r, Client, D, Value>
76where
77 Client: Connection,
78 D: Serialize,
79{
80 type Output = Result<Value>;
81 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + Sync + 'r>>;
82
83 into_future! {execute_value}
84}
85
86impl<'r, Client, D, R> IntoFuture for Content<'r, Client, D, Option<R>>
87where
88 Client: Connection,
89 D: Serialize,
90 R: DeserializeOwned,
91{
92 type Output = Result<Option<R>>;
93 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + Sync + 'r>>;
94
95 into_future! {execute_opt}
96}
97
98impl<'r, Client, D, R> IntoFuture for Content<'r, Client, D, Vec<R>>
99where
100 Client: Connection,
101 D: Serialize,
102 R: DeserializeOwned,
103{
104 type Output = Result<Vec<R>>;
105 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + Sync + 'r>>;
106
107 into_future! {execute_vec}
108}