use crate::Nesting;
#[allow(unused_imports)]
use crate::{Awaiting, Choice, Column, Field, FieldKind};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct Facet<'a> {
pub name: &'a str,
pub mode: Selecting,
pub values: &'a [FacetValue<'a>],
}
impl<'a> Facet<'a> {
#[must_use]
pub const fn new(name: &'a str, mode: Selecting, values: &'a [FacetValue<'a>]) -> Self {
Self { name, mode, values }
}
#[must_use]
pub fn engaged(&self) -> bool {
self.values.iter().any(|value| value.standing.is_picked())
}
#[must_use]
pub fn reach(&self) -> u8 {
self.values
.iter()
.map(|value| value.depth.level)
.max()
.unwrap_or(0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Selecting {
OneOf,
AnyOf,
Range,
Text,
Subtree,
}
impl Selecting {
#[must_use]
pub const fn offers_values(self) -> bool {
matches!(self, Self::OneOf | Self::AnyOf | Self::Subtree)
}
#[must_use]
pub const fn prunes(self) -> bool {
matches!(self, Self::Subtree)
}
#[must_use]
pub const fn accumulates(self) -> bool {
matches!(self, Self::AnyOf | Self::Subtree)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct FacetValue<'a> {
pub value: &'a str,
pub label: &'a str,
pub count: Option<u64>,
pub standing: Standing,
pub depth: Nesting,
pub branching: bool,
}
impl<'a> FacetValue<'a> {
#[must_use]
pub const fn new(value: &'a str, label: &'a str) -> Self {
Self {
value,
label,
count: None,
standing: Standing::Open,
depth: Nesting::top(),
branching: false,
}
}
#[must_use]
pub const fn of(value: &'a str) -> Self {
Self::new(value, value)
}
#[must_use]
pub const fn counted(mut self, count: u64) -> Self {
self.count = Some(count);
self
}
#[must_use]
pub const fn standing(mut self, standing: Standing) -> Self {
self.standing = standing;
self
}
#[must_use]
pub const fn at(mut self, depth: Nesting, branching: bool) -> Self {
self.depth = depth;
self.branching = branching;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[non_exhaustive]
pub enum Standing {
#[default]
Open,
Taken,
Inherited,
Pruned,
}
impl Standing {
#[must_use]
pub const fn is_picked(self) -> bool {
matches!(self, Self::Taken | Self::Pruned)
}
#[must_use]
pub const fn in_force(self) -> bool {
matches!(self, Self::Taken | Self::Inherited)
}
#[must_use]
pub const fn intent(self) -> &'static str {
match self {
Self::Taken | Self::Inherited | Self::Open => "content",
Self::Pruned => "content-secondary",
}
}
}