surrealdb/api/method/
create.rs

1use crate::api::conn::Command;
2use crate::api::method::BoxFuture;
3use crate::api::opt::Resource;
4use crate::api::Connection;
5use crate::api::Result;
6use crate::method::OnceLockExt;
7use crate::sql::Value;
8use crate::Surreal;
9use serde::de::DeserializeOwned;
10use serde::Serialize;
11use std::borrow::Cow;
12use std::future::IntoFuture;
13use std::marker::PhantomData;
14use surrealdb_core::sql::to_value;
15
16use super::Content;
17
18/// A record create future
19#[derive(Debug)]
20#[must_use = "futures do nothing unless you `.await` or poll them"]
21pub struct Create<'r, C: Connection, R> {
22	pub(super) client: Cow<'r, Surreal<C>>,
23	pub(super) resource: Result<Resource>,
24	pub(super) response_type: PhantomData<R>,
25}
26
27impl<C, R> Create<'_, C, R>
28where
29	C: Connection,
30{
31	/// Converts to an owned type which can easily be moved to a different thread
32	pub fn into_owned(self) -> Create<'static, C, R> {
33		Create {
34			client: Cow::Owned(self.client.into_owned()),
35			..self
36		}
37	}
38}
39
40macro_rules! into_future {
41	($method:ident) => {
42		fn into_future(self) -> Self::IntoFuture {
43			let Create {
44				client,
45				resource,
46				..
47			} = self;
48			Box::pin(async move {
49				let router = client.router.extract()?;
50				let cmd = Command::Create {
51					what: resource?.into(),
52					data: None,
53				};
54				router.$method(cmd).await
55			})
56		}
57	};
58}
59
60impl<'r, Client> IntoFuture for Create<'r, Client, Value>
61where
62	Client: Connection,
63{
64	type Output = Result<Value>;
65	type IntoFuture = BoxFuture<'r, Self::Output>;
66
67	into_future! {execute_value}
68}
69
70impl<'r, Client, R> IntoFuture for Create<'r, Client, Option<R>>
71where
72	Client: Connection,
73	R: DeserializeOwned,
74{
75	type Output = Result<Option<R>>;
76	type IntoFuture = BoxFuture<'r, Self::Output>;
77
78	into_future! {execute_opt}
79}
80
81impl<'r, Client, R> IntoFuture for Create<'r, Client, Vec<R>>
82where
83	Client: Connection,
84	R: DeserializeOwned,
85{
86	type Output = Result<Vec<R>>;
87	type IntoFuture = BoxFuture<'r, Self::Output>;
88
89	into_future! {execute_vec}
90}
91
92impl<'r, C, R> Create<'r, C, R>
93where
94	C: Connection,
95{
96	/// Sets content of a record
97	pub fn content<D>(self, data: D) -> Content<'r, C, R>
98	where
99		D: Serialize + 'static,
100	{
101		Content::from_closure(self.client, || {
102			let content = to_value(data)?;
103
104			let data = match content {
105				Value::None | Value::Null => None,
106				content => Some(content),
107			};
108
109			Ok(Command::Create {
110				what: self.resource?.into(),
111				data,
112			})
113		})
114	}
115}