Skip to main content

surrealdb/api/method/
content.rs

1use std::borrow::Cow;
2use std::future::IntoFuture;
3use std::marker::PhantomData;
4
5use serde::de::DeserializeOwned;
6use uuid::Uuid;
7
8use crate::api::conn::Command;
9use crate::api::method::BoxFuture;
10use crate::api::{Connection, Result};
11use crate::method::OnceLockExt;
12use crate::{Surreal, Value};
13
14/// A content future
15///
16/// Content inserts or replaces the contents of a record entirely
17#[derive(Debug)]
18#[must_use = "futures do nothing unless you `.await` or poll them"]
19pub struct Content<'r, C: Connection, R> {
20	#[allow(dead_code)]
21	pub(super) txn: Option<Uuid>,
22	pub(super) client: Cow<'r, Surreal<C>>,
23	pub(super) command: Result<Command>,
24	pub(super) response_type: PhantomData<R>,
25}
26
27impl<'r, C, R> Content<'r, C, R>
28where
29	C: Connection,
30{
31	pub(crate) fn from_closure<F>(client: Cow<'r, Surreal<C>>, txn: Option<Uuid>, f: F) -> Self
32	where
33		F: FnOnce() -> Result<Command>,
34	{
35		Content {
36			txn,
37			client,
38			command: f(),
39			response_type: PhantomData,
40		}
41	}
42
43	/// Converts to an owned type which can easily be moved to a different
44	/// thread
45	pub fn into_owned(self) -> Content<'static, C, R> {
46		Content {
47			client: Cow::Owned(self.client.into_owned()),
48			..self
49		}
50	}
51}
52
53macro_rules! into_future {
54	($method:ident) => {
55		fn into_future(self) -> Self::IntoFuture {
56			let Content {
57				client,
58				command,
59				..
60			} = self;
61			Box::pin(async move {
62				let router = client.inner.router.extract()?;
63				router.$method(command?).await
64			})
65		}
66	};
67}
68
69impl<'r, Client> IntoFuture for Content<'r, Client, Value>
70where
71	Client: Connection,
72{
73	type Output = Result<Value>;
74	type IntoFuture = BoxFuture<'r, Self::Output>;
75
76	into_future! {execute_value}
77}
78
79impl<'r, Client, R> IntoFuture for Content<'r, Client, Option<R>>
80where
81	Client: Connection,
82	R: DeserializeOwned,
83{
84	type Output = Result<Option<R>>;
85	type IntoFuture = BoxFuture<'r, Self::Output>;
86
87	into_future! {execute_opt}
88}
89
90impl<'r, Client, R> IntoFuture for Content<'r, Client, Vec<R>>
91where
92	Client: Connection,
93	R: DeserializeOwned,
94{
95	type Output = Result<Vec<R>>;
96	type IntoFuture = BoxFuture<'r, Self::Output>;
97
98	into_future! {execute_vec}
99}