use std::fmt;
use url::Url;
use self::compare::CompareOp;
use self::criteria::Criterion;
use self::value::ValueKind;
use crate::search::query::Query;
use crate::search::Search;
pub mod compare;
pub mod criteria;
pub mod value;
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct Param(ParamImpl);
impl fmt::Display for Param {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl From<Criterion> for Param {
fn from(criterion: Criterion) -> Self {
Param::criterion(criterion)
}
}
impl Search for Param {
fn write_query(&self, url: &mut Url) -> crate::Result<()> {
super::write_query_string(self, url)
}
}
impl Param {
fn exact(value: impl Into<String>) -> Self {
Param(ParamImpl::ExactName(value.into()))
}
fn criterion(criterion: Criterion) -> Self {
Param(ParamImpl::Criterion(criterion))
}
fn value(kind: ValueKind, value: impl ToString) -> Self {
Param(ParamImpl::Value(kind, value.to_string()))
}
fn comparison(kind: ValueKind, op: CompareOp, value: impl ToString) -> Self {
Param(ParamImpl::Comparison(kind, op, value.to_string()))
}
}
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
enum ParamImpl {
ExactName(String),
Criterion(Criterion),
Value(ValueKind, String),
Comparison(ValueKind, CompareOp, String),
}
impl fmt::Display for ParamImpl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ParamImpl::Criterion(prop) => write!(f, "{prop}"),
ParamImpl::ExactName(name) => write!(f, "!\"{name}\""),
ParamImpl::Value(kind, value) => kind.fmt_value(value.as_str(), f),
ParamImpl::Comparison(kind, op, value) => kind.fmt_comparison(*op, value, f),
}
}
}
pub fn exact(name: impl Into<String>) -> Query {
Query::Param(Param::exact(name))
}