1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*!
# Google AIP-160 Filter Parser with SeaORM Support
This crate provides a parser for [Google AIP-160](https://google.aip.dev/160) filtering expressions
and converts them to SeaORM conditions for database queries.
## Features
- Parse Google AIP-160 filter expressions
- Convert filters to SeaORM conditions
- Support for logical operators (AND, OR, NOT)
- Support for comparison operators (=, !=, <, <=, >, >=, :)
- Support for strings, numbers, booleans, and null values
## Usage
### Parsing a Filter
```rust
use aip_160::parse_filter;
let filter = parse_filter("name = \"John\" AND age > 18").unwrap();
println!("{}", filter);
```
### Converting to SeaORM Condition
```rust,ignore
use sea_orm::entity::prelude::*;
use aip_160::{parse_filter, sea_orm::{FieldMapper, ToSeaOrmCondition}};
// Define your entity
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "users")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: String,
pub email: String,
pub age: i32,
pub active: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}
// Implement the FieldMapper trait
impl FieldMapper for Entity {
fn map_field(&self, field: &str) -> aip_160::error::Result<sea_orm::sea_query::SimpleExpr> {
match field {
"id" => Ok(Column::Id.into_simple_expr()),
"name" => Ok(Column::Name.into_simple_expr()),
"email" => Ok(Column::Email.into_simple_expr()),
"age" => Ok(Column::Age.into_simple_expr()),
"active" => Ok(Column::Active.into_simple_expr()),
_ => Err(aip_160::error::FilterError::InvalidField(field.to_string())),
}
}
}
// Use in your query
async fn find_users(db: &DatabaseConnection, filter_str: &str) -> Result<Vec<Model>, DbErr> {
let filter = parse_filter(filter_str).unwrap();
let condition = filter.to_condition(&Entity).unwrap();
Entity::find()
.filter(condition)
.all(db)
.await
}
```
## Supported Filter Syntax
### Basic Comparisons
- `name = "John"` - Equality
- `age > 18` - Greater than
- `age >= 18` - Greater than or equal
- `age < 65` - Less than
- `age <= 65` - Less than or equal
- `status != "inactive"` - Not equal
- `tags : "important"` - Contains/has (for substring matching)
### Logical Operators
- `name = "John" AND age > 18` - AND
- `status = "active" OR status = "pending"` - OR
- `NOT deleted = true` - NOT
- `(status = "active" OR status = "pending") AND age > 18` - Grouped expressions
### Value Types
- Strings: `"value"` or `'value'`
- Numbers: `42`, `3.14`, `-10`, `1e5`
- Booleans: `true`, `false` (case insensitive)
- Null: `null` (case insensitive)
## Example Filters
```text
name = "John Doe"
age > 18 AND active = true
(status = "active" OR status = "pending") AND created > "2024-01-01"
NOT deleted = true
tags : "important"
price >= 100 AND price <= 1000
email : "@example.com" AND verified = true
```
*/
// Re-export commonly used items
pub use ;
pub use ;
pub use parse_filter;
pub use ;