implements additional traits for filter types (#3036)

* impl ToString for filter::AttrPath
* impl ToString for filter::ScimComplexFilter
* impl ToString for filter::ScimFilter
* impl FromStr for filter::{ScimFilter,ScimComplexFilter,AttrPath}
* derive(Serialize,Deserialize) for filter::{ScimFilter,ScimComplexFilter,AttrPath}

Signed-off-by: Chris Olstrom <chris@olstrom.com>
This commit is contained in:
Chris Olstrom 2024-09-11 21:17:35 -07:00 committed by GitHub
parent d3891e301f
commit 3819d21593
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 84 additions and 3 deletions

View file

@ -42,6 +42,7 @@
- fossdd
- Wei Jian Gan (weijiangan)
- adamcstephens
- Chris Olstrom (colstrom)
## Acknowledgements

View file

@ -1,16 +1,32 @@
#![allow(warnings)]
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::str::FromStr;
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AttrPath {
// Uri: Option<String>,
a: String,
s: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
impl ToString for AttrPath {
fn to_string(&self) -> String {
match self {
Self {
a: attrname,
s: Some(subattr),
} => format!("{attrname}.{subattr}"),
Self {
a: attrname,
s: None,
} => attrname.to_owned(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ScimFilter {
Or(Box<ScimFilter>, Box<ScimFilter>),
And(Box<ScimFilter>, Box<ScimFilter>),
@ -30,7 +46,30 @@ pub enum ScimFilter {
Complex(String, Box<ScimComplexFilter>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
impl ToString for ScimFilter {
fn to_string(&self) -> String {
match self {
Self::And(this, that) => format!("({} and {})", this.to_string(), that.to_string()),
Self::Contains(attrpath, value) => format!("({} co {value})", attrpath.to_string()),
Self::EndsWith(attrpath, value) => format!("({} ew {value})", attrpath.to_string()),
Self::Equal(attrpath, value) => format!("({} eq {value})", attrpath.to_string()),
Self::Greater(attrpath, value) => format!("({} gt {value})", attrpath.to_string()),
Self::GreaterOrEqual(attrpath, value) => {
format!("({} ge {value})", attrpath.to_string())
}
Self::Less(attrpath, value) => format!("({} lt {value})", attrpath.to_string()),
Self::LessOrEqual(attrpath, value) => format!("({} le {value})", attrpath.to_string()),
Self::Not(expr) => format!("(not ({}))", expr.to_string()),
Self::NotEqual(attrpath, value) => format!("({} ne {value})", attrpath.to_string()),
Self::Or(this, that) => format!("({} or {})", this.to_string(), that.to_string()),
Self::Present(attrpath) => format!("({} pr)", attrpath.to_string()),
Self::StartsWith(attrpath, value) => format!("({} sw {value})", attrpath.to_string()),
Self::Complex(attrname, expr) => format!("{attrname}[{}]", expr.to_string()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ScimComplexFilter {
Or(Box<ScimComplexFilter>, Box<ScimComplexFilter>),
And(Box<ScimComplexFilter>, Box<ScimComplexFilter>),
@ -48,6 +87,26 @@ pub enum ScimComplexFilter {
LessOrEqual(String, Value),
}
impl ToString for ScimComplexFilter {
fn to_string(&self) -> String {
match self {
Self::And(this, that) => format!("({} and {})", this.to_string(), that.to_string()),
Self::Contains(attrname, value) => format!("({attrname} co {value})"),
Self::EndsWith(attrname, value) => format!("({attrname} ew {value})"),
Self::Equal(attrname, value) => format!("({attrname} eq {value})"),
Self::Greater(attrname, value) => format!("({attrname} gt {value})"),
Self::GreaterOrEqual(attrname, value) => format!("({attrname} ge {value})"),
Self::Less(attrname, value) => format!("({attrname} lt {value})"),
Self::LessOrEqual(attrname, value) => format!("({attrname} le {value})"),
Self::Not(expr) => format!("(not ({}))", expr.to_string()),
Self::NotEqual(attrname, value) => format!("({attrname} ne {value})"),
Self::Or(this, that) => format!("({} or {})", this.to_string(), that.to_string()),
Self::Present(attrname) => format!("({attrname} pr)"),
Self::StartsWith(attrname, value) => format!("({attrname} sw {value})"),
}
}
}
// separator()* "(" e:term() ")" separator()* { e }
peg::parser! {
@ -213,6 +272,27 @@ peg::parser! {
}
}
impl FromStr for AttrPath {
type Err = peg::error::ParseError<peg::str::LineCol>;
fn from_str(input: &str) -> Result<Self, Self::Err> {
scimfilter::attrpath(input)
}
}
impl FromStr for ScimFilter {
type Err = peg::error::ParseError<peg::str::LineCol>;
fn from_str(input: &str) -> Result<Self, Self::Err> {
scimfilter::parse(input)
}
}
impl FromStr for ScimComplexFilter {
type Err = peg::error::ParseError<peg::str::LineCol>;
fn from_str(input: &str) -> Result<Self, Self::Err> {
scimfilter::parse_complex(input)
}
}
#[cfg(test)]
mod test {
use super::*;