#[repr(C)]pub enum Filter {
Show 17 variants
None,
Equals(FieldName, FilterValue),
NotEquals(FieldName, FilterValue),
Lt(FieldName, FilterValue),
Lte(FieldName, FilterValue),
Gt(FieldName, FilterValue),
Gte(FieldName, FilterValue),
In(FieldName, ValueList),
NotIn(FieldName, ValueList),
Contains(FieldName, FilterValue),
StartsWith(FieldName, FilterValue),
EndsWith(FieldName, FilterValue),
IsNull(FieldName),
IsNotNull(FieldName),
And(Box<[Filter]>),
Or(Box<[Filter]>),
Not(Box<Filter>),
}Expand description
A complete filter that can be converted to SQL.
§Size Optimization
The Filter enum is designed to fit in a single cache line (~64 bytes):
- Field names use
Cow<'static, str>(24 bytes) - Filter values use
FilterValue(40 bytes) - IN/NOT IN use
Vec<FilterValue>(24 bytes) instead of SmallVec - AND/OR use
Box<[Filter]>(16 bytes)
This enables efficient iteration and better CPU cache utilization.
§Zero-Allocation Patterns
For maximum performance, use static strings:
use prax_query::filter::{Filter, FilterValue};
// Zero allocation - static string borrowed
let filter = Filter::Equals("id".into(), FilterValue::Int(42));Variants§
None
No filter (always true).
Equals(FieldName, FilterValue)
Equals comparison.
NotEquals(FieldName, FilterValue)
Not equals comparison.
Lt(FieldName, FilterValue)
Less than comparison.
Lte(FieldName, FilterValue)
Less than or equal comparison.
Gt(FieldName, FilterValue)
Greater than comparison.
Gte(FieldName, FilterValue)
Greater than or equal comparison.
In(FieldName, ValueList)
In a list of values.
NotIn(FieldName, ValueList)
Not in a list of values.
Contains(FieldName, FilterValue)
Contains (LIKE %value%).
StartsWith(FieldName, FilterValue)
Starts with (LIKE value%).
EndsWith(FieldName, FilterValue)
Ends with (LIKE %value).
IsNull(FieldName)
Is null check.
IsNotNull(FieldName)
Is not null check.
And(Box<[Filter]>)
Logical AND of multiple filters.
Uses Box<[Filter]> instead of Vec<Filter> to save 8 bytes per filter
(no capacity field needed since filters are immutable after construction).
Or(Box<[Filter]>)
Logical OR of multiple filters.
Uses Box<[Filter]> instead of Vec<Filter> to save 8 bytes per filter
(no capacity field needed since filters are immutable after construction).
Not(Box<Filter>)
Logical NOT of a filter.
Implementations§
Source§impl Filter
impl Filter
Sourcepub fn and(filters: impl IntoIterator<Item = Filter>) -> Self
pub fn and(filters: impl IntoIterator<Item = Filter>) -> Self
Create an AND filter from an iterator of filters.
Automatically filters out None filters and simplifies single-element combinations.
For known small counts, prefer and2, and3, and5, or and_n for better performance.
Sourcepub fn and2(a: Filter, b: Filter) -> Self
pub fn and2(a: Filter, b: Filter) -> Self
Create an AND filter from exactly two filters.
More efficient than and([a, b]) - avoids Vec allocation.
Sourcepub fn or(filters: impl IntoIterator<Item = Filter>) -> Self
pub fn or(filters: impl IntoIterator<Item = Filter>) -> Self
Create an OR filter from an iterator of filters.
Automatically filters out None filters and simplifies single-element combinations.
For known small counts, prefer or2, or3, or or_n for better performance.
Sourcepub fn or2(a: Filter, b: Filter) -> Self
pub fn or2(a: Filter, b: Filter) -> Self
Create an OR filter from exactly two filters.
More efficient than or([a, b]) - avoids Vec allocation.
Sourcepub fn and_n<const N: usize>(filters: [Filter; N]) -> Self
pub fn and_n<const N: usize>(filters: [Filter; N]) -> Self
Create an AND filter from a fixed-size array (const generic).
This is the most efficient way to create AND filters when the count is known at compile time. It avoids Vec allocation entirely.
§Examples
use prax_query::filter::{Filter, FilterValue};
let filter = Filter::and_n([
Filter::Equals("a".into(), FilterValue::Int(1)),
Filter::Equals("b".into(), FilterValue::Int(2)),
Filter::Equals("c".into(), FilterValue::Int(3)),
]);Sourcepub fn or_n<const N: usize>(filters: [Filter; N]) -> Self
pub fn or_n<const N: usize>(filters: [Filter; N]) -> Self
Create an OR filter from a fixed-size array (const generic).
This is the most efficient way to create OR filters when the count is known at compile time. It avoids Vec allocation entirely.
Sourcepub fn and3(a: Filter, b: Filter, c: Filter) -> Self
pub fn and3(a: Filter, b: Filter, c: Filter) -> Self
Create an AND filter from exactly 3 filters.
Sourcepub fn and4(a: Filter, b: Filter, c: Filter, d: Filter) -> Self
pub fn and4(a: Filter, b: Filter, c: Filter, d: Filter) -> Self
Create an AND filter from exactly 4 filters.
Sourcepub fn and5(a: Filter, b: Filter, c: Filter, d: Filter, e: Filter) -> Self
pub fn and5(a: Filter, b: Filter, c: Filter, d: Filter, e: Filter) -> Self
Create an AND filter from exactly 5 filters.
Sourcepub fn or3(a: Filter, b: Filter, c: Filter) -> Self
pub fn or3(a: Filter, b: Filter, c: Filter) -> Self
Create an OR filter from exactly 3 filters.
Sourcepub fn or4(a: Filter, b: Filter, c: Filter, d: Filter) -> Self
pub fn or4(a: Filter, b: Filter, c: Filter, d: Filter) -> Self
Create an OR filter from exactly 4 filters.
Sourcepub fn or5(a: Filter, b: Filter, c: Filter, d: Filter, e: Filter) -> Self
pub fn or5(a: Filter, b: Filter, c: Filter, d: Filter, e: Filter) -> Self
Create an OR filter from exactly 5 filters.
Sourcepub fn in_i64(
field: impl Into<FieldName>,
values: impl IntoIterator<Item = i64>,
) -> Self
pub fn in_i64( field: impl Into<FieldName>, values: impl IntoIterator<Item = i64>, ) -> Self
Create an IN filter from an iterator of i64 values.
This is optimized for integer lists, avoiding the generic Into<FilterValue>
conversion overhead.
Sourcepub fn in_i32(
field: impl Into<FieldName>,
values: impl IntoIterator<Item = i32>,
) -> Self
pub fn in_i32( field: impl Into<FieldName>, values: impl IntoIterator<Item = i32>, ) -> Self
Create an IN filter from an iterator of i32 values.
Sourcepub fn in_strings(
field: impl Into<FieldName>,
values: impl IntoIterator<Item = String>,
) -> Self
pub fn in_strings( field: impl Into<FieldName>, values: impl IntoIterator<Item = String>, ) -> Self
Create an IN filter from an iterator of string values.
Sourcepub fn in_values(field: impl Into<FieldName>, values: ValueList) -> Self
pub fn in_values(field: impl Into<FieldName>, values: ValueList) -> Self
Create an IN filter from a pre-built ValueList.
Use this when you’ve already constructed a ValueList to avoid re-collection.
Sourcepub fn in_range(field: impl Into<FieldName>, range: Range<i64>) -> Self
pub fn in_range(field: impl Into<FieldName>, range: Range<i64>) -> Self
Create an IN filter from a range of i64 values.
Highly optimized for sequential integer ranges.
Sourcepub fn in_i64_slice(field: impl Into<FieldName>, values: &[i64]) -> Self
pub fn in_i64_slice(field: impl Into<FieldName>, values: &[i64]) -> Self
Create an IN filter from a pre-allocated i64 slice with exact capacity.
This is the most efficient way to create IN filters for i64 values when you have a slice available.
Sourcepub fn in_i32_slice(field: impl Into<FieldName>, values: &[i32]) -> Self
pub fn in_i32_slice(field: impl Into<FieldName>, values: &[i32]) -> Self
Create an IN filter for i32 values from a slice.
Sourcepub fn in_str_slice(field: impl Into<FieldName>, values: &[&str]) -> Self
pub fn in_str_slice(field: impl Into<FieldName>, values: &[&str]) -> Self
Create an IN filter for string values from a slice.
Sourcepub fn in_slice<T: Into<FilterValue> + Clone>(
field: impl Into<FieldName>,
values: &[T],
) -> Self
pub fn in_slice<T: Into<FilterValue> + Clone>( field: impl Into<FieldName>, values: &[T], ) -> Self
Create an IN filter from a slice of values.
This is more efficient than Filter::In(field, values.into()) when you have a slice,
as it avoids intermediate collection.
§Examples
use prax_query::filter::Filter;
let ids: &[i64] = &[1, 2, 3, 4, 5];
let filter = Filter::in_slice("id", ids);Sourcepub fn not_in_slice<T: Into<FilterValue> + Clone>(
field: impl Into<FieldName>,
values: &[T],
) -> Self
pub fn not_in_slice<T: Into<FilterValue> + Clone>( field: impl Into<FieldName>, values: &[T], ) -> Self
Create a NOT IN filter from a slice of values.
§Examples
use prax_query::filter::Filter;
let ids: &[i64] = &[1, 2, 3, 4, 5];
let filter = Filter::not_in_slice("id", ids);Sourcepub fn in_array<T: Into<FilterValue>, const N: usize>(
field: impl Into<FieldName>,
values: [T; N],
) -> Self
pub fn in_array<T: Into<FilterValue>, const N: usize>( field: impl Into<FieldName>, values: [T; N], ) -> Self
Create an IN filter from an array (const generic).
This is useful when you know the size at compile time.
§Examples
use prax_query::filter::Filter;
let filter = Filter::in_array("status", ["active", "pending", "processing"]);Sourcepub fn not_in_array<T: Into<FilterValue>, const N: usize>(
field: impl Into<FieldName>,
values: [T; N],
) -> Self
pub fn not_in_array<T: Into<FilterValue>, const N: usize>( field: impl Into<FieldName>, values: [T; N], ) -> Self
Create a NOT IN filter from an array (const generic).
Sourcepub fn to_sql(&self, param_offset: usize) -> (String, Vec<FilterValue>)
pub fn to_sql(&self, param_offset: usize) -> (String, Vec<FilterValue>)
Generate SQL for this filter with parameter placeholders. Returns (sql, params) where params are the values to bind.
Sourcepub fn and_builder(capacity: usize) -> AndFilterBuilder
pub fn and_builder(capacity: usize) -> AndFilterBuilder
Create a builder for constructing AND filters with pre-allocated capacity.
This is more efficient than using Filter::and() when you know the
approximate number of conditions upfront.
§Examples
use prax_query::filter::{Filter, FilterValue};
// Build an AND filter with pre-allocated capacity for 3 conditions
let filter = Filter::and_builder(3)
.push(Filter::Equals("active".into(), FilterValue::Bool(true)))
.push(Filter::Gt("score".into(), FilterValue::Int(100)))
.push(Filter::IsNotNull("email".into()))
.build();Sourcepub fn or_builder(capacity: usize) -> OrFilterBuilder
pub fn or_builder(capacity: usize) -> OrFilterBuilder
Create a builder for constructing OR filters with pre-allocated capacity.
This is more efficient than using Filter::or() when you know the
approximate number of conditions upfront.
§Examples
use prax_query::filter::{Filter, FilterValue};
// Build an OR filter with pre-allocated capacity for 2 conditions
let filter = Filter::or_builder(2)
.push(Filter::Equals("role".into(), FilterValue::String("admin".into())))
.push(Filter::Equals("role".into(), FilterValue::String("moderator".into())))
.build();Sourcepub fn builder() -> FluentFilterBuilder
pub fn builder() -> FluentFilterBuilder
Create a general-purpose filter builder.
Use this for building complex filter trees with a fluent API.
§Examples
use prax_query::filter::Filter;
let filter = Filter::builder()
.eq("status", "active")
.gt("age", 18)
.is_not_null("email")
.build_and();Trait Implementations§
Source§impl From<StaticFilter> for Filter
impl From<StaticFilter> for Filter
Source§fn from(f: StaticFilter) -> Self
fn from(f: StaticFilter) -> Self
Source§impl IntoFilter for Filter
impl IntoFilter for Filter
Source§fn into_filter(self) -> Filter
fn into_filter(self) -> Filter
impl StructuralPartialEq for Filter
Auto Trait Implementations§
impl Freeze for Filter
impl RefUnwindSafe for Filter
impl Send for Filter
impl Sync for Filter
impl Unpin for Filter
impl UnwindSafe for Filter
Blanket Implementations§
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dest: *mut u8)
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)