use crate::Expr;
use datafusion_common::ScalarValue;
pub fn lit<T: Literal>(n: T) -> Expr {
n.lit()
}
pub fn lit_timestamp_nano<T: TimestampLiteral>(n: T) -> Expr {
n.lit_timestamp_nano()
}
pub trait Literal {
fn lit(&self) -> Expr;
}
pub trait TimestampLiteral {
fn lit_timestamp_nano(&self) -> Expr;
}
impl Literal for &str {
fn lit(&self) -> Expr {
Expr::Literal(ScalarValue::from(*self))
}
}
impl Literal for String {
fn lit(&self) -> Expr {
Expr::Literal(ScalarValue::from(self.as_ref()))
}
}
impl Literal for &String {
fn lit(&self) -> Expr {
Expr::Literal(ScalarValue::from(self.as_ref()))
}
}
impl Literal for Vec<u8> {
fn lit(&self) -> Expr {
Expr::Literal(ScalarValue::Binary(Some((*self).to_owned())))
}
}
impl Literal for &[u8] {
fn lit(&self) -> Expr {
Expr::Literal(ScalarValue::Binary(Some((*self).to_owned())))
}
}
impl Literal for ScalarValue {
fn lit(&self) -> Expr {
Expr::Literal(self.clone())
}
}
macro_rules! make_literal {
($TYPE:ty, $SCALAR:ident, $DOC: expr) => {
#[doc = $DOC]
impl Literal for $TYPE {
fn lit(&self) -> Expr {
Expr::Literal(ScalarValue::$SCALAR(Some(self.clone())))
}
}
};
}
macro_rules! make_nonzero_literal {
($TYPE:ty, $SCALAR:ident, $DOC: expr) => {
#[doc = $DOC]
impl Literal for $TYPE {
fn lit(&self) -> Expr {
Expr::Literal(ScalarValue::$SCALAR(Some(self.get())))
}
}
};
}
macro_rules! make_timestamp_literal {
($TYPE:ty, $SCALAR:ident, $DOC: expr) => {
#[doc = $DOC]
impl TimestampLiteral for $TYPE {
fn lit_timestamp_nano(&self) -> Expr {
Expr::Literal(ScalarValue::TimestampNanosecond(
Some((self.clone()).into()),
None,
))
}
}
};
}
make_literal!(bool, Boolean, "literal expression containing a bool");
make_literal!(f32, Float32, "literal expression containing an f32");
make_literal!(f64, Float64, "literal expression containing an f64");
make_literal!(i8, Int8, "literal expression containing an i8");
make_literal!(i16, Int16, "literal expression containing an i16");
make_literal!(i32, Int32, "literal expression containing an i32");
make_literal!(i64, Int64, "literal expression containing an i64");
make_literal!(u8, UInt8, "literal expression containing a u8");
make_literal!(u16, UInt16, "literal expression containing a u16");
make_literal!(u32, UInt32, "literal expression containing a u32");
make_literal!(u64, UInt64, "literal expression containing a u64");
make_nonzero_literal!(
std::num::NonZeroI8,
Int8,
"literal expression containing an i8"
);
make_nonzero_literal!(
std::num::NonZeroI16,
Int16,
"literal expression containing an i16"
);
make_nonzero_literal!(
std::num::NonZeroI32,
Int32,
"literal expression containing an i32"
);
make_nonzero_literal!(
std::num::NonZeroI64,
Int64,
"literal expression containing an i64"
);
make_nonzero_literal!(
std::num::NonZeroU8,
UInt8,
"literal expression containing a u8"
);
make_nonzero_literal!(
std::num::NonZeroU16,
UInt16,
"literal expression containing a u16"
);
make_nonzero_literal!(
std::num::NonZeroU32,
UInt32,
"literal expression containing a u32"
);
make_nonzero_literal!(
std::num::NonZeroU64,
UInt64,
"literal expression containing a u64"
);
make_timestamp_literal!(i8, Int8, "literal expression containing an i8");
make_timestamp_literal!(i16, Int16, "literal expression containing an i16");
make_timestamp_literal!(i32, Int32, "literal expression containing an i32");
make_timestamp_literal!(i64, Int64, "literal expression containing an i64");
make_timestamp_literal!(u8, UInt8, "literal expression containing a u8");
make_timestamp_literal!(u16, UInt16, "literal expression containing a u16");
make_timestamp_literal!(u32, UInt32, "literal expression containing a u32");
#[cfg(test)]
mod test {
use std::num::NonZeroU32;
use super::*;
use crate::expr_fn::col;
#[test]
fn test_lit_nonzero() {
let expr = col("id").eq(lit(NonZeroU32::new(1).unwrap()));
let expected = col("id").eq(lit(ScalarValue::UInt32(Some(1))));
assert_eq!(expr, expected);
}
#[test]
fn test_lit_timestamp_nano() {
let expr = col("time").eq(lit_timestamp_nano(10)); let expected =
col("time").eq(lit(ScalarValue::TimestampNanosecond(Some(10), None)));
assert_eq!(expr, expected);
let i: i64 = 10;
let expr = col("time").eq(lit_timestamp_nano(i));
assert_eq!(expr, expected);
let i: u32 = 10;
let expr = col("time").eq(lit_timestamp_nano(i));
assert_eq!(expr, expected);
}
}