surrealdb/api/method/
create.rs1use 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#[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 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 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}