This commit is contained in:
Brandon Thomas committed 2024-06-30 20:45:10 -04:00
1 parent 10b8e29b56
commit d8ea5054de
1 file changed
+123 -27
@@ -1,6 +1,8 @@
use std::collections::HashSet;
use once_cell::sync::Lazy;
use serde_json::{json, Value};
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
use enums::by_table::media_files::media_file_type::MediaFileType;
@@ -15,14 +17,17 @@ static JSON_QUERY : Lazy<Value> = Lazy::new(|| {
json
});
pub struct SearchArgs {
pub struct SearchArgs<'a> {
pub search_term: &'a str,
pub maybe_media_classes: Option<HashSet<MediaFileClass>>,
pub maybe_media_types: Option<HashSet<MediaFileType>>,
pub maybe_engine_categories: Option<HashSet<MediaFileEngineCategory>>,
}
pub fn search_media_files(args: SearchArgs) -> AnyhowResult<()> {
let query = build_query(args)?;
Ok(())
}
fn build_query(args: SearchArgs) -> AnyhowResult<Value> {
@@ -45,11 +50,11 @@ fn build_query(args: SearchArgs) -> AnyhowResult<Value> {
predicates.push(engine_categories_predicate(engine_categories));
}
println!("Predicates: {:?}", predicates);
Some(json!(predicates))
})?;
println!("QUERY: {}", query);
Ok(query)
}
@@ -62,7 +67,7 @@ fn must_be_not_deleted() -> Value {
}
fn media_classes_predicate(media_classes: &HashSet<MediaFileClass>) -> Value {
let predicates : Vec<Value> = media_classes.iter()
should_predicates(media_classes.iter()
.map(|media_type| {
json!({
"term": {
@@ -70,17 +75,11 @@ fn media_classes_predicate(media_classes: &HashSet<MediaFileClass>) -> Value {
}
})
})
.collect();
json!({
"bool": {
"should": predicates,
}
})
.collect())
}
fn media_types_predicate(media_types: &HashSet<MediaFileType>) -> Value {
let predicates : Vec<Value> = media_types.iter()
should_predicates(media_types.iter()
.map(|media_type| {
json!({
"term": {
@@ -88,17 +87,11 @@ fn media_types_predicate(media_types: &HashSet<MediaFileType>) -> Value {
}
})
})
.collect();
json!({
"bool": {
"should": predicates,
}
})
.collect())
}
fn engine_categories_predicate(engine_categories: &HashSet<MediaFileEngineCategory>) -> Value {
let predicates : Vec<Value> = engine_categories.iter()
should_predicates(engine_categories.iter()
.map(|engine_category| {
json!({
"term": {
@@ -106,8 +99,11 @@ fn engine_categories_predicate(engine_categories: &HashSet<MediaFileEngineCatego
}
})
})
.collect();
.collect())
}
// NB: "Should" is a logical OR.
fn should_predicates(predicates: Vec<Value>) -> Value {
json!({
"bool": {
"should": predicates,
@@ -117,16 +113,116 @@ fn engine_categories_predicate(engine_categories: &HashSet<MediaFileEngineCatego
#[cfg(test)]
mod tests {
use crate::searches::search_media_files::SearchArgs;
use std::collections::HashSet;
use std::iter::FromIterator;
use serde_json::Value;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
use enums::by_table::media_files::media_file_type::MediaFileType;
use crate::searches::search_media_files::{build_query, SearchArgs};
#[test]
fn test() {
super::search_media_files(SearchArgs {
fn test_default_search() {
let search = build_query(SearchArgs {
search_term: "foo",
maybe_media_classes: None,
maybe_media_types: None,
maybe_engine_categories: None,
}).expect("should function");
}).unwrap();
assert_eq!(1, 2);
let value = jsonpath_lib::select(
&search, "$.query.bool.must[0].bool.must[0].term.is_deleted").unwrap();
assert_eq!(value[0], &Value::Bool(false));
}
}
#[test]
fn test_media_class() {
let search = build_query(SearchArgs {
search_term: "bar",
maybe_media_classes: Some(HashSet::from_iter(vec![
MediaFileClass::Dimensional,
MediaFileClass::Image,
])),
maybe_media_types: None,
maybe_engine_categories: None,
}).unwrap();
let value = select(&search, "$.query.bool.must[0].bool.must[0].term.is_deleted");
assert_eq!(value[0], &Value::Bool(false));
let values = select_str_values(
&search, "$.query.bool.must[0].bool.must[1].bool.should[*].term.media_class");
assert_eq!(values.len(), 2);
assert!(values.contains(&"image"));
assert!(values.contains(&"dimensional"));
}
#[test]
fn test_media_type() {
let search = build_query(SearchArgs {
search_term: "baz",
maybe_media_classes: None,
maybe_media_types: Some(HashSet::from_iter(vec![
MediaFileType::Glb,
MediaFileType::Png,
])),
maybe_engine_categories: None,
}).unwrap();
let value = select(&search, "$.query.bool.must[0].bool.must[0].term.is_deleted");
assert_eq!(value[0], &Value::Bool(false));
let values = select_str_values(
&search, "$.query.bool.must[0].bool.must[1].bool.should[*].term.media_type");
assert_eq!(values.len(), 2);
assert!(values.contains(&"glb"));
assert!(values.contains(&"png"));
}
#[test]
fn test_engine_category() {
let search = build_query(SearchArgs {
search_term: "bin",
maybe_media_classes: None,
maybe_media_types: None,
maybe_engine_categories: Some(HashSet::from_iter(vec![
MediaFileEngineCategory::Animation,
MediaFileEngineCategory::Character,
])),
}).unwrap();
let value = select(&search, "$.query.bool.must[0].bool.must[0].term.is_deleted");
assert_eq!(value[0], &Value::Bool(false));
let values = select_str_values(
&search, "$.query.bool.must[0].bool.must[1].bool.should[*].term.maybe_engine_category");
assert_eq!(values.len(), 2);
assert!(values.contains(&"animation"));
assert!(values.contains(&"character"));
}
fn select<'a>(search: &'a Value, path: &str) -> Vec<&'a Value> {
jsonpath_lib::select(search, path).unwrap()
}
fn select_str_values<'a>(search: &'a Value, path: &str) -> Vec<&'a str> {
select(search, path).into_iter()
.map(|value| {
match value {
Value::String(inner) => inner.as_str(),
_ => panic!("Expected string"),
}
})
.collect()
}
}