/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin */ use crate::{DEBUG_TAGREG, Filter, MultiBehaviour, Query, Sort, SortOrder}; use jellyobject::{Path, Registry, Tag}; impl Query { pub fn show_debug(&self) -> String { if let Some(r) = DEBUG_TAGREG.get() { self.show(r) } else { "[debug tag registry disabled]".to_string() } } pub fn show(&self, reg: &Registry) -> String { let mut o = String::new(); if !matches!(self.filter, Filter::True) { o += &format!("FILTER {} ", self.filter.show(reg)) } if !matches!(self.sort, Sort::None) { o += &format!("SORT {} ", self.sort.show(reg)) } o } } impl Filter { pub fn show(&self, reg: &Registry) -> String { match self { Filter::True => "TRUE".to_string(), Filter::All(filters) => format!( "({})", filters .iter() .map(|f| f.show(reg)) .collect::>() .join(" AND ") ), Filter::Any(filters) => format!( "({})", filters .iter() .map(|f| f.show(reg)) .collect::>() .join(" OR ") ), Filter::Match(path, value) => { format!( "{} = {}", show_path(reg, path), show_value(reg, *path.0.last().unwrap(), value) ) } Filter::Has(path) => show_path(reg, path), } } } impl Sort { pub fn show(&self, reg: &Registry) -> String { match self { Sort::None => "NONE".to_string(), Sort::Value(vs) => { format!( "{} BY {} {}", match vs.order { SortOrder::Ascending => "ASCENDING", SortOrder::Descending => "DESCENDING", }, match vs.multi { MultiBehaviour::Count => "COUNT", MultiBehaviour::First => "FIRST", MultiBehaviour::ForEach => "EACH", MultiBehaviour::Max => "MAX", MultiBehaviour::Min => "MIN", }, show_path(reg, &vs.path), ) } Sort::TextSearch(path, value) => { format!("TEXT SEARCH {} = {value:?}", show_path(reg, path),) } } } } fn show_path(reg: &Registry, path: &Path) -> String { path.0 .iter() .map(|s| reg.name(*s)) .collect::>() .join(".") } fn show_value(reg: &Registry, tag: Tag, value: &[u8]) -> String { if let Some(info) = reg.info(tag) && let Some(ty) = info.r#type { use jellyobject::types::*; match () { () if ty == STR => format!("{:?}", str::from_utf8(value).unwrap()), () if ty == U32 => format!("{:?}", u32::from_be_bytes(value.try_into().unwrap())), () if ty == U64 => format!("{:?}", u64::from_be_bytes(value.try_into().unwrap())), () if ty == F64 => format!("{:?}", f64::from_be_bytes(value.try_into().unwrap())), () => format!("{value:?}"), } } else { format!("{value:?}") } }