Skip to main content

oxi/store/issues/
filter.rs

1//! Filter predicates for [`crate::store::issues::FileIssueStore::list`].
2
3use crate::store::issues::types::{Issue, Priority, Status};
4
5/// Filter for `list`. All fields optional (None = no constraint).
6#[derive(Debug, Clone, Default)]
7pub struct IssueFilter {
8    pub status: Option<Status>,
9    pub priority: Option<Priority>,
10    pub label: Option<String>,
11    pub assigned_to_session: Option<String>,
12    /// Text substring match on title (case-insensitive).
13    pub text: Option<String>,
14}
15
16impl IssueFilter {
17    /// Check if an issue matches this filter. All non-None fields must match.
18    pub fn matches(&self, issue: &Issue) -> bool {
19        if let Some(s) = self.status
20            && issue.meta.status != s
21        {
22            return false;
23        }
24        if let Some(p) = self.priority
25            && issue.meta.priority != p
26        {
27            return false;
28        }
29        if let Some(ref label) = self.label
30            && !issue.meta.labels.iter().any(|l| l == label)
31        {
32            return false;
33        }
34        if let Some(ref session) = self.assigned_to_session {
35            let mine = issue
36                .meta
37                .assigned_to
38                .as_ref()
39                .map(|a| &a.session == session)
40                .unwrap_or(false);
41            if !mine {
42                return false;
43            }
44        }
45        if let Some(ref text) = self.text
46            && !issue
47                .meta
48                .title
49                .to_lowercase()
50                .contains(&text.to_lowercase())
51        {
52            return false;
53        }
54        true
55    }
56}