Separate Future into standalone type
This commit is contained in:
parent
ff65ef56fc
commit
426fce00a8
7 changed files with 92 additions and 49 deletions
|
@ -1,7 +0,0 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
||||
pub fn run(_: &Context, expr: Value) -> Result<Value, Error> {
|
||||
Ok(expr)
|
||||
}
|
|
@ -8,7 +8,6 @@ pub mod cast;
|
|||
pub mod count;
|
||||
pub mod crypto;
|
||||
pub mod duration;
|
||||
pub mod future;
|
||||
pub mod geo;
|
||||
pub mod http;
|
||||
pub mod is;
|
||||
|
|
|
@ -308,14 +308,14 @@ impl Datastore {
|
|||
/// use surrealdb::Datastore;
|
||||
/// use surrealdb::Error;
|
||||
/// use surrealdb::Session;
|
||||
/// use surrealdb::sql::Function;
|
||||
/// use surrealdb::sql::Future;
|
||||
/// use surrealdb::sql::Value;
|
||||
///
|
||||
/// #[tokio::main]
|
||||
/// async fn main() -> Result<(), Error> {
|
||||
/// let ds = Datastore::new("memory").await?;
|
||||
/// let ses = Session::for_kv();
|
||||
/// let val = Value::Function(Box::new(Function::Future(Value::True)));
|
||||
/// let val = Value::Future(Box::new(Future(Value::True)));
|
||||
/// let res = ds.compute(val, &ses, None, false).await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
|
|
|
@ -19,7 +19,6 @@ use std::fmt;
|
|||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
|
||||
pub enum Function {
|
||||
Future(Value),
|
||||
Cast(String, Value),
|
||||
Normal(String, Vec<Value>),
|
||||
Script(Script, Vec<Value>),
|
||||
|
@ -116,13 +115,6 @@ impl Function {
|
|||
let opt = &opt.dive(1)?;
|
||||
// Process the function type
|
||||
match self {
|
||||
Self::Future(v) => match opt.futures {
|
||||
true => {
|
||||
let v = v.compute(ctx, opt, txn, doc).await?;
|
||||
fnc::future::run(ctx, v)
|
||||
}
|
||||
false => Ok(self.to_owned().into()),
|
||||
},
|
||||
Self::Cast(s, x) => {
|
||||
let v = x.compute(ctx, opt, txn, doc).await?;
|
||||
fnc::cast::run(ctx, s, v)
|
||||
|
@ -158,7 +150,6 @@ impl Function {
|
|||
impl fmt::Display for Function {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Future(ref e) => write!(f, "<future> {{ {} }}", e),
|
||||
Self::Cast(ref s, ref e) => write!(f, "<{}> {}", s, e),
|
||||
Self::Script(ref s, ref e) => {
|
||||
write!(f, "function({}) {{{}}}", Fmt::comma_separated(e), s)
|
||||
|
@ -169,7 +160,7 @@ impl fmt::Display for Function {
|
|||
}
|
||||
|
||||
pub fn function(i: &str) -> IResult<&str, Function> {
|
||||
alt((normal, script, future, cast))(i)
|
||||
alt((normal, script, cast))(i)
|
||||
}
|
||||
|
||||
fn normal(i: &str) -> IResult<&str, Function> {
|
||||
|
@ -195,19 +186,6 @@ fn script(i: &str) -> IResult<&str, Function> {
|
|||
Ok((i, Function::Script(v, a)))
|
||||
}
|
||||
|
||||
fn future(i: &str) -> IResult<&str, Function> {
|
||||
let (i, _) = char('<')(i)?;
|
||||
let (i, _) = tag("future")(i)?;
|
||||
let (i, _) = char('>')(i)?;
|
||||
let (i, _) = mightbespace(i)?;
|
||||
let (i, _) = char('{')(i)?;
|
||||
let (i, _) = mightbespace(i)?;
|
||||
let (i, v) = value(i)?;
|
||||
let (i, _) = mightbespace(i)?;
|
||||
let (i, _) = char('}')(i)?;
|
||||
Ok((i, Function::Future(v)))
|
||||
}
|
||||
|
||||
fn cast(i: &str) -> IResult<&str, Function> {
|
||||
let (i, _) = char('<')(i)?;
|
||||
let (i, s) = function_casts(i)?;
|
||||
|
@ -478,7 +456,6 @@ fn function_type(i: &str) -> IResult<&str, &str> {
|
|||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::sql::expression::Expression;
|
||||
use crate::sql::test::Parse;
|
||||
|
||||
#[test]
|
||||
|
@ -531,16 +508,6 @@ mod tests {
|
|||
assert_eq!(out, Function::Cast(String::from("string"), 1.2345.into()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function_future_expression() {
|
||||
let sql = "<future> { 1.2345 + 5.4321 }";
|
||||
let res = function(sql);
|
||||
assert!(res.is_ok());
|
||||
let out = res.unwrap().1;
|
||||
assert_eq!("<future> { 1.2345 + 5.4321 }", format!("{}", out));
|
||||
assert_eq!(out, Function::Future(Value::from(Expression::parse("1.2345 + 5.4321"))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function_script_expression() {
|
||||
let sql = "function() { return this.tags.filter(t => { return t.length > 3; }); }";
|
||||
|
|
68
lib/src/sql/future.rs
Normal file
68
lib/src/sql/future.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Transaction;
|
||||
use crate::err::Error;
|
||||
use crate::sql::comment::mightbespace;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::value::{value, Value};
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::char;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
|
||||
pub struct Future(pub Value);
|
||||
|
||||
impl Future {
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Prevent long future chains
|
||||
let opt = &opt.dive(1)?;
|
||||
// Process the future if enabled
|
||||
match opt.futures {
|
||||
true => self.0.compute(ctx, opt, txn, doc).await?.ok(),
|
||||
false => Ok(self.clone().into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Future {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "<future> {{ {} }}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn future(i: &str) -> IResult<&str, Future> {
|
||||
let (i, _) = char('<')(i)?;
|
||||
let (i, _) = tag("future")(i)?;
|
||||
let (i, _) = char('>')(i)?;
|
||||
let (i, _) = mightbespace(i)?;
|
||||
let (i, _) = char('{')(i)?;
|
||||
let (i, _) = mightbespace(i)?;
|
||||
let (i, v) = value(i)?;
|
||||
let (i, _) = mightbespace(i)?;
|
||||
let (i, _) = char('}')(i)?;
|
||||
Ok((i, Future(v)))
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::sql::expression::Expression;
|
||||
use crate::sql::test::Parse;
|
||||
|
||||
#[test]
|
||||
fn future_expression() {
|
||||
let sql = "<future> { 1.2345 + 5.4321 }";
|
||||
let res = future(sql);
|
||||
assert!(res.is_ok());
|
||||
let out = res.unwrap().1;
|
||||
assert_eq!("<future> { 1.2345 + 5.4321 }", format!("{}", out));
|
||||
assert_eq!(out, Future(Value::from(Expression::parse("1.2345 + 5.4321"))));
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ pub(crate) mod fetch;
|
|||
pub(crate) mod field;
|
||||
pub(crate) mod fmt;
|
||||
pub(crate) mod function;
|
||||
pub(crate) mod future;
|
||||
pub(crate) mod geometry;
|
||||
pub(crate) mod graph;
|
||||
pub(crate) mod group;
|
||||
|
@ -79,6 +80,7 @@ pub use self::fetch::Fetchs;
|
|||
pub use self::field::Field;
|
||||
pub use self::field::Fields;
|
||||
pub use self::function::Function;
|
||||
pub use self::future::Future;
|
||||
pub use self::geometry::Geometry;
|
||||
pub use self::graph::Graph;
|
||||
pub use self::group::Group;
|
||||
|
|
|
@ -14,6 +14,7 @@ use crate::sql::error::IResult;
|
|||
use crate::sql::expression::{expression, Expression};
|
||||
use crate::sql::fmt::Fmt;
|
||||
use crate::sql::function::{function, Function};
|
||||
use crate::sql::future::{future, Future};
|
||||
use crate::sql::geometry::{geometry, Geometry};
|
||||
use crate::sql::id::Id;
|
||||
use crate::sql::idiom::{idiom, Idiom};
|
||||
|
@ -117,6 +118,7 @@ pub enum Value {
|
|||
Regex(Regex),
|
||||
Range(Box<Range>),
|
||||
Edges(Box<Edges>),
|
||||
Future(Box<Future>),
|
||||
Constant(Constant),
|
||||
Function(Box<Function>),
|
||||
Subquery(Box<Subquery>),
|
||||
|
@ -255,6 +257,12 @@ impl From<Edges> for Value {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Future> for Value {
|
||||
fn from(v: Future) -> Self {
|
||||
Value::Future(Box::new(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Function> for Value {
|
||||
fn from(v: Function) -> Self {
|
||||
Value::Function(Box::new(v))
|
||||
|
@ -861,8 +869,8 @@ impl Value {
|
|||
Value::Idiom(v) => v.simplify(),
|
||||
Value::Strand(v) => v.0.to_string().into(),
|
||||
Value::Datetime(v) => v.0.to_string().into(),
|
||||
Value::Future(_) => "fn::future".to_string().into(),
|
||||
Value::Function(v) => match v.as_ref() {
|
||||
Function::Future(_) => "fn::future".to_string().into(),
|
||||
Function::Script(_, _) => "fn::script".to_string().into(),
|
||||
Function::Normal(f, _) => f.to_string().into(),
|
||||
Function::Cast(_, v) => v.to_idiom(),
|
||||
|
@ -1234,6 +1242,7 @@ impl fmt::Display for Value {
|
|||
Value::Regex(v) => write!(f, "{}", v),
|
||||
Value::Range(v) => write!(f, "{}", v),
|
||||
Value::Edges(v) => write!(f, "{}", v),
|
||||
Value::Future(v) => write!(f, "{}", v),
|
||||
Value::Constant(v) => write!(f, "{}", v),
|
||||
Value::Function(v) => write!(f, "{}", v),
|
||||
Value::Subquery(v) => write!(f, "{}", v),
|
||||
|
@ -1273,6 +1282,7 @@ impl Value {
|
|||
Value::Idiom(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Value::Array(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Value::Object(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Value::Future(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Value::Constant(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Value::Function(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Value::Subquery(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
|
@ -1309,10 +1319,11 @@ impl Serialize for Value {
|
|||
Value::Regex(v) => s.serialize_newtype_variant("Value", 17, "Regex", v),
|
||||
Value::Range(v) => s.serialize_newtype_variant("Value", 18, "Range", v),
|
||||
Value::Edges(v) => s.serialize_newtype_variant("Value", 19, "Edges", v),
|
||||
Value::Constant(v) => s.serialize_newtype_variant("Value", 20, "Constant", v),
|
||||
Value::Function(v) => s.serialize_newtype_variant("Value", 21, "Function", v),
|
||||
Value::Subquery(v) => s.serialize_newtype_variant("Value", 22, "Subquery", v),
|
||||
Value::Expression(v) => s.serialize_newtype_variant("Value", 23, "Expression", v),
|
||||
Value::Future(v) => s.serialize_newtype_variant("Value", 20, "Future", v),
|
||||
Value::Constant(v) => s.serialize_newtype_variant("Value", 21, "Constant", v),
|
||||
Value::Function(v) => s.serialize_newtype_variant("Value", 22, "Function", v),
|
||||
Value::Subquery(v) => s.serialize_newtype_variant("Value", 23, "Subquery", v),
|
||||
Value::Expression(v) => s.serialize_newtype_variant("Value", 24, "Expression", v),
|
||||
}
|
||||
} else {
|
||||
match self {
|
||||
|
@ -1407,6 +1418,7 @@ pub fn single(i: &str) -> IResult<&str, Value> {
|
|||
map(datetime, Value::from),
|
||||
map(duration, Value::from),
|
||||
map(geometry, Value::from),
|
||||
map(future, Value::from),
|
||||
map(unique, Value::from),
|
||||
map(number, Value::from),
|
||||
map(object, Value::from),
|
||||
|
@ -1438,6 +1450,7 @@ pub fn select(i: &str) -> IResult<&str, Value> {
|
|||
map(datetime, Value::from),
|
||||
map(duration, Value::from),
|
||||
map(geometry, Value::from),
|
||||
map(future, Value::from),
|
||||
map(unique, Value::from),
|
||||
map(number, Value::from),
|
||||
map(object, Value::from),
|
||||
|
@ -1459,6 +1472,7 @@ pub fn what(i: &str) -> IResult<&str, Value> {
|
|||
map(subquery, Value::from),
|
||||
map(function, Value::from),
|
||||
map(constant, Value::from),
|
||||
map(future, Value::from),
|
||||
map(param, Value::from),
|
||||
map(model, Value::from),
|
||||
map(edges, Value::from),
|
||||
|
|
Loading…
Reference in a new issue