surrealdb_expr/expr/
mod.rs1use anyhow::Result;
4
5use crate::val::Value;
6
7pub mod access;
8pub mod access_type;
9pub mod algorithm;
10pub mod base;
11pub mod block;
12pub mod bytesize;
13pub mod changefeed;
14pub mod computed_deps;
15pub mod cond;
16pub mod constant;
17pub mod convert;
18pub mod data;
19pub mod dir;
20pub mod error;
21pub mod explain;
22pub mod expression;
23pub mod fetch;
24pub mod field;
25pub mod filter;
26pub mod function;
27pub mod function_facts;
28pub mod graphql_config;
29pub mod group;
30pub mod idiom;
31pub mod index_kind;
32pub mod kind;
33pub mod language;
34pub mod limit;
35pub mod literal;
36pub mod lookup;
37pub mod match_plan;
38pub use crate::sql::method;
42pub mod mock;
43pub mod model;
44pub mod mutation;
45pub mod operation;
46pub mod operator;
47pub mod order;
48pub mod output;
49pub mod param;
50pub mod part;
51pub mod paths;
52pub mod permission;
53pub mod plan;
54pub mod record_id;
55pub mod reference;
56pub mod script;
57pub mod split;
58pub mod start;
59pub mod table_type;
60pub mod tokenizer;
61pub mod user;
62pub mod variables;
63pub mod view;
64pub mod with;
65
66pub mod decimal;
67pub mod module;
68
69pub mod closure;
70pub mod statements;
71pub mod visit;
72
73pub use self::access_type::{AccessType, JwtAccess, RecordAccess};
74pub use self::algorithm::Algorithm;
75pub use self::base::Base;
76pub use self::block::Block;
77pub use self::bytesize::Bytesize;
78pub use self::changefeed::ChangeFeed;
79pub use self::closure::ClosureExpr;
80pub use self::cond::Cond;
81pub use self::constant::Constant;
82pub use self::data::Data;
83pub use self::dir::Dir;
84pub use self::error::Error;
85pub use self::explain::Explain;
86pub use self::expression::{ExplainFormat, Expr};
87pub use self::fetch::{Fetch, Fetchs};
88pub use self::field::{Field, Fields};
89pub use self::filter::Filter;
90pub use self::function::{Function, FunctionCall};
91pub use self::group::{Group, Groups};
92pub use self::idiom::Idiom;
93pub use self::kind::{Kind, KindLiteral};
94pub use self::limit::Limit;
95pub use self::literal::{Literal, ObjectEntry};
96pub use self::lookup::Lookup;
97#[allow(unused_imports)]
100pub use self::match_plan::MatchPlan;
101pub use self::mock::Mock;
102pub use self::model::Model;
103pub use self::module::{ModuleExecutable, SiloExecutable, SurrealismExecutable};
104pub use self::operation::Operation;
105pub use self::operator::{AssignOperator, BinaryOperator, PostfixOperator, PrefixOperator};
106pub use self::order::Order;
107pub use self::output::Output;
108pub use self::param::Param;
109pub use self::part::Part;
110pub use self::plan::{LogicalPlan, TopLevelExpr};
111pub use self::record_id::{RecordIdKeyGen, RecordIdKeyLit, RecordIdKeyRangeLit, RecordIdLit};
112pub use self::script::Script;
113pub use self::split::{Split, Splits};
114pub use self::start::Start;
115pub use self::statements::{DefineAnalyzerStatement, SelectStatement, SleepStatement};
116pub use self::tokenizer::{SegmentLanguage, Tokenizer};
117pub use self::view::View;
118pub use self::with::With;
119
120pub type FlowResult<T> = Result<T, ControlFlow>;
122
123#[derive(Debug)]
127pub enum ControlFlow {
128 Break,
129 Continue,
130 Return(Value),
131 Err(anyhow::Error),
132}
133
134impl std::fmt::Display for ControlFlow {
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 match self {
137 ControlFlow::Break => write!(f, "BREAK"),
138 ControlFlow::Continue => write!(f, "CONTINUE"),
139 ControlFlow::Return(v) => write!(f, "RETURN {:?}", v),
140 ControlFlow::Err(e) => write!(f, "{}", e),
141 }
142 }
143}
144
145impl From<anyhow::Error> for ControlFlow {
146 fn from(error: anyhow::Error) -> Self {
147 ControlFlow::Err(error)
148 }
149}
150
151impl From<Error> for ControlFlow {
152 fn from(error: Error) -> Self {
155 ControlFlow::Err(anyhow::Error::new(error))
156 }
157}
158
159impl ControlFlow {
160 pub fn is_ignorable(&self) -> bool {
166 match self {
167 ControlFlow::Break | ControlFlow::Continue | ControlFlow::Return(_) => false,
169 ControlFlow::Err(e) => match e.downcast_ref::<Error>() {
170 Some(err) => err.is_ignorable(),
171 None => false,
173 },
174 }
175 }
176}
177
178pub trait ControlFlowExt<T> {
203 fn context<C: std::fmt::Display + Send + Sync + 'static>(
206 self,
207 context: C,
208 ) -> std::result::Result<T, ControlFlow>;
209
210 #[allow(dead_code)] fn with_context<C, F>(self, f: F) -> std::result::Result<T, ControlFlow>
214 where
215 C: std::fmt::Display + Send + Sync + 'static,
216 F: FnOnce() -> C;
217}
218
219impl<T, E: Into<anyhow::Error>> ControlFlowExt<T> for std::result::Result<T, E> {
220 fn context<C: std::fmt::Display + Send + Sync + 'static>(
221 self,
222 context: C,
223 ) -> std::result::Result<T, ControlFlow> {
224 self.map_err(|e| ControlFlow::Err(e.into().context(context)))
225 }
226
227 fn with_context<C, F>(self, f: F) -> std::result::Result<T, ControlFlow>
228 where
229 C: std::fmt::Display + Send + Sync + 'static,
230 F: FnOnce() -> C,
231 {
232 self.map_err(|e| ControlFlow::Err(e.into().context(f())))
233 }
234}
235
236impl<T> ControlFlowExt<T> for Option<T> {
237 fn context<C: std::fmt::Display + Send + Sync + 'static>(
238 self,
239 context: C,
240 ) -> std::result::Result<T, ControlFlow> {
241 self.ok_or_else(|| ControlFlow::Err(anyhow::anyhow!("{}", context)))
242 }
243
244 fn with_context<C, F>(self, f: F) -> std::result::Result<T, ControlFlow>
245 where
246 C: std::fmt::Display + Send + Sync + 'static,
247 F: FnOnce() -> C,
248 {
249 self.ok_or_else(|| ControlFlow::Err(anyhow::anyhow!("{}", f())))
250 }
251}