1use crate::{
2 ctx::Context,
3 dbs::{Options, Transaction},
4 doc::CursorDoc,
5 err::Error,
6 iam::Action,
7 ident::Ident,
8 value::Value,
9 Permission,
10};
11use revision::revisioned;
12use serde::{Deserialize, Serialize};
13use std::{fmt, ops::Deref, str};
14
15pub(crate) const TOKEN: &str = "$surrealdb::private::crate::Param";
16
17#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
18#[serde(rename = "$surrealdb::private::crate::Param")]
19#[revisioned(revision = 1)]
20pub struct Param(pub Ident);
21
22impl From<Ident> for Param {
23 fn from(v: Ident) -> Self {
24 Self(v)
25 }
26}
27
28impl From<String> for Param {
29 fn from(v: String) -> Self {
30 Self(v.into())
31 }
32}
33
34impl From<&str> for Param {
35 fn from(v: &str) -> Self {
36 Self(v.into())
37 }
38}
39
40impl Deref for Param {
41 type Target = Ident;
42 fn deref(&self) -> &Self::Target {
43 &self.0
44 }
45}
46
47impl Param {
48 pub(crate) async fn compute(
50 &self,
51 ctx: &Context<'_>,
52 opt: &Options,
53 txn: &Transaction,
54 doc: Option<&CursorDoc<'_>>,
55 ) -> Result<Value, Error> {
56 match self.as_str() {
58 "this" | "self" => match doc {
60 Some(v) => v.doc.compute(ctx, opt, txn, doc).await,
62 None => Ok(Value::None),
64 },
65 v => match ctx.value(v) {
67 Some(v) => v.compute(ctx, opt, txn, doc).await,
69 None => {
71 let val = {
72 let mut run = txn.lock().await;
74 run.get_and_cache_db_param(opt.ns(), opt.db(), v).await
76 };
77 match val {
79 Ok(val) => {
81 if opt.check_perms(Action::View) {
83 match &val.permissions {
84 Permission::Full => (),
85 Permission::None => {
86 return Err(Error::ParamPermissions {
87 name: v.to_owned(),
88 })
89 }
90 Permission::Specific(e) => {
91 let opt = &opt.new_with_perms(false);
93 if !e.compute(ctx, opt, txn, doc).await?.is_truthy() {
95 return Err(Error::ParamPermissions {
96 name: v.to_owned(),
97 });
98 }
99 }
100 }
101 }
102 Ok(val.value.to_owned())
104 }
105 Err(_) => Ok(Value::None),
107 }
108 }
109 },
110 }
111 }
112}
113
114impl fmt::Display for Param {
115 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116 write!(f, "${}", &self.0)
117 }
118}