struct Provenance {
name: String,
stored_stripped: String,
}
#[derive(Default)]
pub struct SavedSearchBreadcrumb {
pinned: Option<Provenance>,
}
impl SavedSearchBreadcrumb {
pub fn set(&mut self, name: Option<String>, stored_query: &str) {
self.pinned = match name {
Some(name) if !stored_query.trim().is_empty() => Some(Provenance {
name,
stored_stripped: strip(stored_query),
}),
_ => None,
};
}
pub fn on_query_consumed(
&mut self,
accepted: Option<String>,
query: &str,
query_is_blank: bool,
) {
match accepted {
Some(name) => self.set(if query_is_blank { None } else { Some(name) }, query),
None if query_is_blank => self.pinned = None,
None => {}
}
}
pub fn label(&self, query: &str) -> Option<String> {
let p = self.pinned.as_ref()?;
Some(if strip(query) != p.stored_stripped {
format!("{} • edited", p.name)
} else {
p.name.clone()
})
}
pub fn border_title(&self, query: &str, fallback: &str) -> String {
match self.label(query) {
Some(label) => format!(" ‹ {label} › "),
None => fallback.to_string(),
}
}
}
fn strip(query: &str) -> String {
kimun_core::strip_order_directive(query)
}
#[cfg(test)]
mod tests {
use super::*;
fn pinned(stored: &str) -> SavedSearchBreadcrumb {
let mut b = SavedSearchBreadcrumb::default();
b.set(Some("todo".into()), stored);
b
}
#[test]
fn unedited_label_is_the_name() {
assert_eq!(pinned("#todo").label("#todo").as_deref(), Some("todo"));
}
#[test]
fn diverged_query_marks_edited() {
assert_eq!(
pinned("#todo").label("#todox").as_deref(),
Some("todo • edited")
);
}
#[test]
fn order_directive_change_is_not_edited() {
assert_eq!(
pinned("#todo").label("#todo or:title").as_deref(),
Some("todo")
);
}
#[test]
fn set_with_blank_query_does_not_pin() {
let mut b = SavedSearchBreadcrumb::default();
b.set(Some("todo".into()), " ");
assert_eq!(b.label(" "), None);
}
#[test]
fn accept_with_blank_expansion_clears_rather_than_pins() {
let mut b = SavedSearchBreadcrumb::default();
b.on_query_consumed(Some("empty".into()), "", true);
assert_eq!(b.label(""), None);
}
#[test]
fn blank_query_clears_sticky_breadcrumb() {
let mut b = pinned("#todo");
b.on_query_consumed(None, "", true);
assert_eq!(b.label(""), None);
}
#[test]
fn non_blank_edit_keeps_sticky_breadcrumb() {
let mut b = pinned("#todo");
b.on_query_consumed(None, "#todox", false);
assert_eq!(b.label("#todox").as_deref(), Some("todo • edited"));
}
#[test]
fn border_title_chevrons_label_else_fallback() {
assert_eq!(
pinned("#todo").border_title("#todo", " Query"),
" ‹ todo › "
);
assert_eq!(
SavedSearchBreadcrumb::default().border_title("#todo", " Query"),
" Query"
);
}
}