Skip to main content

Expressive

Trait Expressive 

Source
pub trait Expressive<T> {
    // Required method
    fn expr(&self) -> Expression<T>;

    // Provided method
    fn preview(&self) -> String
       where T: Debug + Display { ... }
}
Expand description

Trait for creating custom SQL constructs that can be converted to expressions.

The Expressive trait allows you to define reusable SQL patterns and complex query constructs that can be seamlessly integrated into larger expressions. This is particularly useful for creating database-specific syntax, common query patterns, or complex operations like identifiers with automatic escaping.

§Example

Create a wrapper for table/field names which will escape only if we use a reserved keyword.

use vantage_expressions::{Expression, expr};
use vantage_expressions::traits::expressive::Expressive;

#[derive(Debug, Clone)]
pub struct Identifier {
    identifier: String,
}

impl Identifier {
    pub fn new(identifier: impl Into<String>) -> Self {
        Self { identifier: identifier.into() }
    }

    fn needs_escaping(&self) -> bool {
        let reserved_keywords = ["SELECT", "FROM", "TO", "IN"];
        let upper = self.identifier.to_uppercase();
        self.identifier.contains(' ') || reserved_keywords.contains(&upper.as_str())
    }
}

impl Expressive<serde_json::Value> for Identifier {
    fn expr(&self) -> Expression<serde_json::Value> {
        if self.needs_escaping() {
            expr!(format!("`{}`", self.identifier))
        } else {
            expr!(self.identifier.clone())
        }
    }
}

// Usage - Expressive types work automatically in expr! macro
let field = Identifier::new("user_name");
let escaped = Identifier::new("SELECT"); // Reserved keyword

// Direct usage in expr! macro - no .expr() calls needed
let query = expr!(
    "SELECT {}, {}, {} FROM {}",
    (Identifier::new("from")),
    (Identifier::new("to")),
    (Identifier::new("subject")),
    (Identifier::new("emails"))
);
// Result: SELECT `from`, `to`, subject FROM emails

Required Methods§

Source

fn expr(&self) -> Expression<T>

Convert this construct into an Expression<T>.

This method should return an Expression that represents the SQL or query language construct. The expression can contain nested expressions, parameters, or deferred computations.

Types implementing this trait can be used directly in the expr! macro with parentheses syntax: (identifier) - the conversion happens automatically.

Provided Methods§

Source

fn preview(&self) -> String
where T: Debug + Display,

Preview the expression as a formatted string.

This method provides a convenient way to preview expressions without needing to call expr().preview() explicitly.

Implementations on Foreign Types§

Source§

impl Expressive<bool> for bool

Source§

impl Expressive<f32> for f32

Source§

impl Expressive<f64> for f64

Source§

impl Expressive<i8> for i8

Source§

fn expr(&self) -> Expression<i8>

Source§

impl Expressive<i16> for i16

Source§

impl Expressive<i32> for i32

Source§

impl Expressive<i64> for i64

Source§

impl Expressive<u8> for u8

Source§

fn expr(&self) -> Expression<u8>

Source§

impl Expressive<u16> for u16

Source§

impl Expressive<u32> for u32

Source§

impl Expressive<AnySqliteType> for &str

Source§

impl Expressive<AnySqliteType> for bool

Source§

impl Expressive<AnySqliteType> for f32

Source§

impl Expressive<AnySqliteType> for f64

Source§

impl Expressive<AnySqliteType> for i8

Source§

impl Expressive<AnySqliteType> for i16

Source§

impl Expressive<AnySqliteType> for i32

Source§

impl Expressive<AnySqliteType> for i64

Source§

impl Expressive<AnySqliteType> for u8

Source§

impl Expressive<AnySqliteType> for u16

Source§

impl Expressive<AnySqliteType> for u32

Source§

impl Expressive<AnySqliteType> for String

Source§

impl Expressive<AnySqliteType> for DateTime<Utc>

Source§

impl Expressive<AnySqliteType> for NaiveDate

Source§

impl Expressive<AnySqliteType> for NaiveDateTime

Source§

impl Expressive<AnySqliteType> for NaiveTime

Source§

impl Expressive<AnySqliteType> for Decimal

Source§

impl<T> Expressive<T> for MockColumn<T>
where T: ColumnType,

Source§

fn expr(&self) -> Expression<T>

Implementors§

Source§

impl Expressive<Value> for MockSelect

Source§

impl Expressive<AnySqliteType> for SqliteCondition

Condition chaining: the condition type wraps Expression<AnyType>, so implementing Expressive<AnyType> gives it the operation trait via the blanket above.

Source§

impl Expressive<AnySqliteType> for Concat<AnySqliteType>

Available on crate feature sqlite only.
Source§

impl Expressive<AnySqliteType> for DateFormat<AnySqliteType>

Available on crate feature sqlite only.
Source§

impl Expressive<AnySqliteType> for Identifier

Available on crate feature sqlite only.
Source§

impl Expressive<AnySqliteType> for Iif<AnySqliteType>

Available on crate feature sqlite only.
Source§

impl Expressive<AnySqliteType> for Interval

Available on crate feature sqlite only.
Source§

impl Expressive<AnySqliteType> for JsonExtract<AnySqliteType>

Available on crate feature sqlite only.
Source§

impl Expressive<AnySqliteType> for Point

Available on crate feature sqlite only.
Source§

impl Expressive<AnySqliteType> for Ternary<AnySqliteType>

Available on crate feature sqlite only.
Source§

impl Expressive<AnySqliteType> for SqliteDelete

Source§

impl Expressive<AnySqliteType> for SqliteInsert

Source§

impl Expressive<AnySqliteType> for SqliteSelect

Source§

impl Expressive<AnySqliteType> for SqliteUpdate

Source§

impl Expressive<AnySqliteType> for SqliteIdent

Source§

impl Expressive<AnySqliteType> for AnySqliteType

Source§

impl<'a, DS, T, R> Expressive<T> for AssociatedExpression<'a, DS, T, R>
where T: Clone, DS: ExprDataSource<T>,

Source§

impl<T> Expressive<T> for Column<T>
where T: ColumnType,

Source§

impl<T> Expressive<T> for Expression<T>
where T: Clone,

Source§

impl<T: Debug + Display + Clone> Expressive<T> for Case<T>

Source§

impl<T: Debug + Display + Clone> Expressive<T> for Fx<T>

Source§

impl<T: Debug + Display + Clone> Expressive<T> for Union<T>