diff --git a/src/lib.rs b/src/lib.rs index e6e122e..e9b8338 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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('$') {