surrealdb/api/method/
content.rs

1use 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/// A content future
21///
22/// Content inserts or replaces the contents of a record entirely
23#[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	/// Converts to an owned type which can easily be moved to a different thread
39	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}