filter: implement fmt::Display

This commit is contained in:
2025-11-21 18:36:54 +09:00
parent e4ece7d6b2
commit 8aba3d8859

View File

@@ -1,4 +1,4 @@
use std::str::SplitWhitespace;
use std::{fmt, str::SplitWhitespace};
use serde::{Deserialize, Serialize};
@@ -51,6 +51,102 @@ pub enum Filter {
PrioCmp(ComparisonOperator, Priority),
}
impl fmt::Display for Filter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Filter::Not(inner) => write!(f, "(NOT ({}))", inner),
Filter::And(left, right) => write!(f, "({} AND {})", left, right),
Filter::EqTag(tag, case_sensitivity, negated) => {
let op = if *negated { "!=" } else { "==" };
let cs = match case_sensitivity {
CaseSensitivity::CaseSensitive => "_cs",
CaseSensitivity::CaseInsensitive => "_ci",
CaseSensitivity::CommandDependent => "",
};
write!(f, "({} {}{} '{}')", tag.key(), op, cs, tag.value())
}
Filter::Contains(tag, case_sensitivity, negated) => {
let op = if *negated { "!contains" } else { "contains" };
let cs = match case_sensitivity {
CaseSensitivity::CaseSensitive => "_cs",
CaseSensitivity::CaseInsensitive => "_ci",
CaseSensitivity::CommandDependent => "",
};
write!(f, "({} {}{} '{}')", tag.key(), op, cs, tag.value())
}
Filter::StartsWith(tag, case_sensitivity, negated) => {
let op = if *negated {
"!starts_with"
} else {
"starts_with"
};
let cs = match case_sensitivity {
CaseSensitivity::CaseSensitive => "_cs",
CaseSensitivity::CaseInsensitive => "_ci",
CaseSensitivity::CommandDependent => "",
};
write!(f, "({} {}{} '{}')", tag.key(), op, cs, tag.value())
}
Filter::PerlRegex(tag) => {
write!(f, "({} =~ '{}')", tag.key(), tag.value())
}
Filter::NegPerlRegex(tag) => {
write!(f, "({} !~ '{}')", tag.key(), tag.value())
}
Filter::EqUri(uri) => {
write!(f, "(uri == '{}')", uri)
}
Filter::Base(path) => {
write!(f, "(base '{}')", path)
}
Filter::ModifiedSince(timestamp) => {
write!(f, "(modified-since '{}')", timestamp)
}
Filter::AudioFormatEq {
sample_rate,
bits,
channels,
} => {
write!(
f,
"(AudioFormat == '{}:{}:{}')",
sample_rate, bits, channels
)
}
Filter::AudioFormatEqMask {
sample_rate,
bits,
channels,
} => {
let sr_str = match sample_rate {
Some(sr) => sr.to_string(),
None => "*".to_string(),
};
let bits_str = match bits {
Some(b) => b.to_string(),
None => "*".to_string(),
};
let ch_str = match channels {
Some(c) => c.to_string(),
None => "*".to_string(),
};
write!(f, "(AudioFormat =~ '{}:{}:{}')", sr_str, bits_str, ch_str)
}
Filter::PrioCmp(op, prio) => {
let op_str = match op {
ComparisonOperator::Equal => "==",
ComparisonOperator::NotEqual => "!=",
ComparisonOperator::GreaterThan => ">",
ComparisonOperator::GreaterThanOrEqual => ">=",
ComparisonOperator::LessThan => "<",
ComparisonOperator::LessThanOrEqual => "<=",
};
write!(f, "(prio {} {})", op_str, prio)
}
}
}
}
pub fn parse_filter(parts: &mut SplitWhitespace<'_>) -> Result<Filter, RequestParserError> {
// TODO: count parentheses and extract the full filter string
unimplemented!()