Skip to main content

oxicode_agent/issues/
filter.rs

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