use std::borrow::Cow;
use crate::ast::*;
impl<'a> And<'a> {
pub fn new_boxed(operands: Vec<Box<Expr<'a>>>) -> Self {
And { operands }
}
pub fn new(operands: Vec<Expr<'a>>) -> Self {
And {
operands: operands.into_iter().map(Box::new).collect(),
}
}
}
impl<'a> FromIterator<Expr<'a>> for And<'a> {
fn from_iter<I: IntoIterator<Item = Expr<'a>>>(iter: I) -> Self {
And {
operands: iter.into_iter().map(Box::new).collect(),
}
}
}
impl<'a> Between<'a> {
pub fn new_borrowed<S0: AsRef<str> + ?Sized>(
field: &'a S0,
lo: Value<'a>,
hi: Value<'a>,
) -> Self {
Between {
field: Cow::Borrowed(field.as_ref()),
lo,
hi,
}
}
}
impl Between<'static> {
pub fn new_owned<S0: Into<String>>(field: S0, lo: Value<'static>, hi: Value<'static>) -> Self {
Between {
field: Cow::Owned(field.into()),
lo,
hi,
}
}
}
impl<'a> Compare<'a> {
pub fn new_borrowed<S0: AsRef<str> + ?Sized>(
field: &'a S0,
op: BinOp,
value: Value<'a>,
) -> Self {
Compare {
field: Cow::Borrowed(field.as_ref()),
op,
value,
}
}
}
impl Compare<'static> {
pub fn new_owned<S0: Into<String>>(field: S0, op: BinOp, value: Value<'static>) -> Self {
Compare {
field: Cow::Owned(field.into()),
op,
value,
}
}
}
impl<'a> Empty<'a> {
pub fn new_borrowed<S0: AsRef<str> + ?Sized>(field: &'a S0) -> Self {
Empty {
field: Cow::Borrowed(field.as_ref()),
}
}
}
impl Empty<'static> {
pub fn new_owned<S0: Into<String>>(field: S0) -> Self {
Empty {
field: Cow::Owned(field.into()),
}
}
}
impl<'a> Expr<'a> {
pub fn and_expr_boxed(operands: Vec<Box<Expr<'a>>>) -> Self {
Expr::And(Box::new(And::new_boxed(operands)))
}
pub fn and_expr(operands: Vec<Expr<'a>>) -> Self {
Expr::And(Box::new(And::new(operands)))
}
pub fn or_expr_boxed(operands: Vec<Box<Expr<'a>>>) -> Self {
Expr::Or(Box::new(Or::new_boxed(operands)))
}
pub fn or_expr(operands: Vec<Expr<'a>>) -> Self {
Expr::Or(Box::new(Or::new(operands)))
}
pub fn not_expr(inner: Expr<'a>) -> Self {
Expr::Not(Box::new(inner))
}
pub fn compare_expr(v: Compare<'a>) -> Self {
Expr::Compare(v)
}
pub fn between_expr(v: Between<'a>) -> Self {
Expr::Between(v)
}
pub fn not_between_expr(v: Between<'a>) -> Self {
Expr::NotBetween(v)
}
pub fn in_expr(v: In<'a>) -> Self {
Expr::In(v)
}
pub fn not_in_expr(v: In<'a>) -> Self {
Expr::NotIn(v)
}
pub fn is_empty_expr(v: Empty<'a>) -> Self {
Expr::IsEmpty(v)
}
pub fn is_null_expr(v: Empty<'a>) -> Self {
Expr::IsNull(v)
}
pub fn is_not_empty_expr(v: Empty<'a>) -> Self {
Expr::IsNotEmpty(v)
}
pub fn is_not_null_expr(v: Empty<'a>) -> Self {
Expr::IsNotNull(v)
}
pub fn or(self, other: Expr<'a>) -> Self {
let mut operands = match self {
Expr::Or(a) => a.operands,
lhs => vec![Box::new(lhs)],
};
match other {
Expr::Or(b) => operands.extend(b.operands),
rhs => operands.push(Box::new(rhs)),
}
Expr::Or(Box::new(Or { operands }))
}
pub fn and(self, other: Expr<'a>) -> Self {
let mut operands = match self {
Expr::And(a) => a.operands,
lhs => vec![Box::new(lhs)],
};
match other {
Expr::And(b) => operands.extend(b.operands),
rhs => operands.push(Box::new(rhs)),
}
Expr::And(Box::new(And { operands }))
}
}
impl<'a> In<'a> {
pub fn new_borrowed<S0: AsRef<str> + ?Sized>(field: &'a S0, values: Vec<Value<'a>>) -> Self {
In {
field: Cow::Borrowed(field.as_ref()),
values,
}
}
}
impl In<'static> {
pub fn new_owned<S0: Into<String>>(field: S0, values: Vec<Value<'static>>) -> Self {
In {
field: Cow::Owned(field.into()),
values,
}
}
}
impl Now {
pub fn new() -> Self {
Now {}
}
}
impl<'a> Or<'a> {
pub fn new_boxed(operands: Vec<Box<Expr<'a>>>) -> Self {
Or { operands }
}
pub fn new(operands: Vec<Expr<'a>>) -> Self {
Or {
operands: operands.into_iter().map(Box::new).collect(),
}
}
}
impl<'a> FromIterator<Expr<'a>> for Or<'a> {
fn from_iter<I: IntoIterator<Item = Expr<'a>>>(iter: I) -> Self {
Or {
operands: iter.into_iter().map(Box::new).collect(),
}
}
}
impl<'a> Participant<'a> {
pub fn new_borrowed<S0: AsRef<str> + ?Sized, S1: AsRef<str> + ?Sized>(
r#type: &'a S0,
id: &'a S1,
) -> Self {
Participant {
r#type: Cow::Borrowed(r#type.as_ref()),
id: Cow::Borrowed(id.as_ref()),
}
}
}
impl Participant<'static> {
pub fn new_owned<S0: Into<String>, S1: Into<String>>(r#type: S0, id: S1) -> Self {
Participant {
r#type: Cow::Owned(r#type.into()),
id: Cow::Owned(id.into()),
}
}
}
impl<'a> Value<'a> {
pub fn string_borrowed<S: AsRef<str> + ?Sized>(s: &'a S) -> Self {
Value::String(Cow::Borrowed(s.as_ref()))
}
pub fn enum_borrowed<S: AsRef<str> + ?Sized>(s: &'a S) -> Self {
Value::Enum(Cow::Borrowed(s.as_ref()))
}
pub fn integer_borrowed<S: AsRef<str> + ?Sized>(s: &'a S) -> Self {
Value::Integer(Cow::Borrowed(s.as_ref()))
}
pub fn float_borrowed<S: AsRef<str> + ?Sized>(s: &'a S) -> Self {
Value::Float(Cow::Borrowed(s.as_ref()))
}
pub fn boolean(v: Boolean) -> Self {
Value::Boolean(v)
}
pub fn date_borrowed<S: AsRef<str> + ?Sized>(s: &'a S) -> Self {
Value::Date(Cow::Borrowed(s.as_ref()))
}
pub fn date_time_borrowed<S: AsRef<str> + ?Sized>(s: &'a S) -> Self {
Value::DateTime(Cow::Borrowed(s.as_ref()))
}
pub fn participant(v: Participant<'a>) -> Self {
Value::Participant(v)
}
pub fn now() -> Self {
Value::Now(Now {})
}
}
impl Value<'static> {
pub fn string_owned<S: Into<String>>(s: S) -> Self {
Value::String(Cow::Owned(s.into()))
}
pub fn enum_owned<S: Into<String>>(s: S) -> Self {
Value::Enum(Cow::Owned(s.into()))
}
pub fn integer_owned<S: Into<String>>(s: S) -> Self {
Value::Integer(Cow::Owned(s.into()))
}
pub fn float_owned<S: Into<String>>(s: S) -> Self {
Value::Float(Cow::Owned(s.into()))
}
pub fn date_owned<S: Into<String>>(s: S) -> Self {
Value::Date(Cow::Owned(s.into()))
}
pub fn date_time_owned<S: Into<String>>(s: S) -> Self {
Value::DateTime(Cow::Owned(s.into()))
}
pub fn integer(v: i32) -> Self {
Value::Integer(Cow::Owned(v.to_string()))
}
pub fn float(v: f64) -> crate::error::BqlResult<Self> {
if !v.is_finite() {
return Err(crate::error::BqlError::new(
0,
"non-finite float has no BQL representation",
));
}
let mut s = format!("{v}");
if !s.bytes().any(|b| matches!(b, b'.' | b'e' | b'E')) {
s.push_str(".0");
}
Ok(Value::Float(Cow::Owned(s)))
}
}