This commit is contained in:
JMARyA 2024-02-09 11:21:09 +01:00
parent b28b4a4e04
commit d1419a2198
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263

View file

@ -37,7 +37,7 @@ fn greater_than_num(a: &serde_json::Value, b: &serde_json::Value) -> bool {
}
}
#[derive(Debug)]
#[derive(Debug, Clone, Copy)]
/// Represents errors that can occur while processing filters.
pub enum FilterError {
/// Indicates that the schema of the filter is invalid.
@ -94,9 +94,8 @@ pub fn try_matches(
.map(|sub_filter| matches(sub_filter, obj))
.collect();
return Ok(!and_list_bool.iter().any(|x| !x));
} else {
return Err(FilterError::InvalidFilter);
}
return Err(FilterError::InvalidFilter);
}
"$or" => {
if let serde_json::Value::Array(or_list) = op_arg {
@ -105,9 +104,8 @@ pub fn try_matches(
.map(|sub_filter| matches(sub_filter, obj))
.collect();
return Ok(or_list_bool.iter().any(|x| *x));
} else {
return Err(FilterError::InvalidFilter);
}
return Err(FilterError::InvalidFilter);
}
_ => {
if op.starts_with('$') {
@ -117,34 +115,40 @@ pub fn try_matches(
}
}
let mut conditions = vec![];
for (key, val) in filter {
if val.is_object() {
let val_keys: Vec<_> = val.as_object().unwrap().keys().collect();
if val_keys.first().unwrap().starts_with('$') {
return match_operator(val, obj, key.as_str());
conditions.push(match_operator(val, obj, key.as_str()));
} else {
// nested
for (_, _) in val.as_object().unwrap() {
let new_filter = filter.get(key).unwrap();
if let Some(val) = obj_map.get(key) {
return try_matches(new_filter, val);
conditions.push(try_matches(new_filter, val));
} else {
return Err(FilterError::KeyNotFound);
}
}
}
continue;
}
if let Some(valb) = obj_map.get(key) {
if val != valb {
return Ok(false);
conditions.push(Ok(false));
}
} else {
return Err(FilterError::KeyNotFound);
}
}
Ok(true)
conditions.iter().find(|x| x.is_err()).map_or_else(
|| Ok(!conditions.iter().map(|x| x.unwrap()).any(|x| !x)),
|possible_error| *possible_error,
)
}
fn match_operator(
@ -162,30 +166,26 @@ fn match_operator(
"$lt" => {
if let Some(a) = obj.get(key) {
return Ok(less_than_num(a, op_arg));
} else {
return Err(FilterError::KeyNotFound);
}
return Err(FilterError::KeyNotFound);
}
"$lte" => {
if let Some(a) = obj.get(key) {
return Ok(less_than_num(a, op_arg) || a == op_arg);
} else {
return Err(FilterError::KeyNotFound);
}
return Err(FilterError::KeyNotFound);
}
"$gt" => {
if let Some(valb) = obj.get(key) {
return Ok(greater_than_num(valb, op_arg));
} else {
return Err(FilterError::KeyNotFound);
}
return Err(FilterError::KeyNotFound);
}
"$gte" => {
if let Some(a) = obj.get(key) {
return Ok(greater_than_num(a, op_arg) || a == op_arg);
} else {
return Err(FilterError::KeyNotFound);
}
return Err(FilterError::KeyNotFound);
}
"$not" => {
if let Some(serde_json::Value::Object(inner)) = val.get("$not") {
@ -193,46 +193,39 @@ fn match_operator(
key: inner
});
return Ok(!try_matches(&new_filter, raw_obj)?);
} else {
return Err(FilterError::InvalidFilter);
}
return Err(FilterError::InvalidFilter);
}
"$ne" => {
if let Some(valb) = obj.get(key) {
return Ok(valb != op_arg);
} else {
return Err(FilterError::KeyNotFound);
}
return Err(FilterError::KeyNotFound);
}
"$in" => {
if let Some(valb) = obj.get(key) {
if let serde_json::Value::Array(list) = valb {
return Ok(list.iter().any(|x| x == op_arg));
} else {
return Err(FilterError::InvalidFilter);
}
} else {
return Err(FilterError::KeyNotFound);
return Err(FilterError::InvalidFilter);
}
return Err(FilterError::KeyNotFound);
}
"$nin" => {
if let Some(valb) = obj.get(key) {
if let serde_json::Value::Array(list) = valb {
return Ok(!list.iter().any(|x| x == op_arg));
} else {
return Err(FilterError::InvalidFilter);
}
} else {
return Err(FilterError::KeyNotFound);
return Err(FilterError::InvalidFilter);
}
return Err(FilterError::KeyNotFound);
}
"$exists" => {
if let serde_json::Value::Bool(exists) = op_arg {
let valb = obj.get(key).is_some();
return Ok(*exists == valb);
} else {
return Err(FilterError::InvalidFilter);
}
return Err(FilterError::InvalidFilter);
}
"$size" => {
if let Some(serde_json::Value::Array(list)) = obj.get(key) {
@ -240,24 +233,20 @@ fn match_operator(
if let serde_json::Value::Number(pref_size) = op_arg {
let pref_size = pref_size.as_u64().unwrap();
return Ok(pref_size == val_size);
} else {
return Err(FilterError::InvalidFilter);
}
} else {
return Err(FilterError::KeyNotFound);
return Err(FilterError::InvalidFilter);
}
return Err(FilterError::KeyNotFound);
}
"$regex" => {
if let serde_json::Value::String(regex_pattern) = op_arg {
if let Some(serde_json::Value::String(valb)) = obj.get(key) {
let pattern = regex::Regex::new(regex_pattern).unwrap();
return Ok(pattern.is_match(valb));
} else {
return Err(FilterError::KeyNotFound);
}
} else {
return Err(FilterError::InvalidFilter);
return Err(FilterError::KeyNotFound);
}
return Err(FilterError::InvalidFilter);
}
"$type" => {
if let Some(valb) = obj.get(key) {
@ -271,12 +260,10 @@ fn match_operator(
"boolean" => valb.is_boolean(),
_ => false,
});
} else {
return Err(FilterError::InvalidFilter);
}
} else {
return Err(FilterError::KeyNotFound);
return Err(FilterError::InvalidFilter);
}
return Err(FilterError::KeyNotFound);
}
_ => {
if op.starts_with('$') {