use std::time::Duration;
use revision::revisioned;
use surrealdb_strand::Strand;
use surrealdb_types::{SqlFormat, ToSql};
use crate::catalog::base::Base;
use crate::expr::statements::info::InfoStructure;
use crate::kvs::impl_kv_value_revisioned;
use crate::sql;
use crate::val::{Array, Value};
#[revisioned(revision = 1)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct UserDefinition {
pub name: Strand,
pub hash: String,
pub code: String,
pub roles: Vec<String>,
pub token_duration: Option<Duration>,
pub session_duration: Option<Duration>,
pub comment: Option<String>,
pub base: Base,
}
impl UserDefinition {
fn redacted(mut self) -> Self {
if !self.hash.is_empty() {
self.hash = super::REDACTED.to_string();
}
self
}
fn to_sql_definition(&self) -> sql::statements::define::DefineUserStatement {
let this = self.clone().redacted();
sql::statements::define::DefineUserStatement {
kind: sql::statements::define::DefineKind::Default,
name: sql::Expr::Idiom(sql::Idiom::field(this.name)),
base: sql::Base::from(crate::expr::Base::from(this.base)),
pass_type: sql::statements::define::user::PassType::Hash(this.hash),
roles: this.roles,
token_duration: this
.token_duration
.map(|d| {
sql::Expr::Literal(sql::Literal::Duration(crate::types::PublicDuration::from(
d,
)))
})
.unwrap_or_else(|| sql::Expr::Literal(sql::Literal::None)),
session_duration: this
.session_duration
.map(|d| {
sql::Expr::Literal(sql::Literal::Duration(crate::types::PublicDuration::from(
d,
)))
})
.unwrap_or_else(|| sql::Expr::Literal(sql::Literal::None)),
comment: this
.comment
.map(|c| sql::Expr::Literal(sql::Literal::String(c.into())))
.unwrap_or(sql::Expr::Literal(sql::Literal::None)),
}
}
}
impl ToSql for &UserDefinition {
fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
self.to_sql_definition().fmt_sql(f, fmt)
}
}
impl InfoStructure for UserDefinition {
fn structure(self) -> Value {
let this = self.redacted();
Value::from(map! {
"name" => Value::String(this.name.clone()),
"hash" => this.hash.into(),
"roles" => Array::from(this.roles.into_iter().map(Value::from).collect::<Vec<_>>()).into(),
"duration" => Value::from(map! {
"token" => this.token_duration.map(Value::from).unwrap_or(Value::None),
"session" => this.session_duration.map(Value::from).unwrap_or(Value::None),
}),
"comment", if let Some(v) = this.comment => v.into(),
})
}
}
impl_kv_value_revisioned!(UserDefinition);