Skip to main content

FilterField

Enum FilterField 

Source
pub enum FilterField {
Show 13 variants Assignee, Label, Status, Priority, Cycle, Milestone, Reviewer, StartDate, DueDate, Parent, Category, Project, Epic,
}
Expand description

A selectable structured-filter criterion.

FilterField::ALL is the single ordered field list the filter modal renders its rows from (risk: field/modal drift) and StructuredFilter evaluates over — adding a criterion (FR-011) is one more Option<String> field on StructuredFilter plus one variant / match arm here.

Variants§

§

Assignee

§

Label

§

Status

§

Priority

§

Cycle

§

Milestone

§

Reviewer

§

StartDate

§

DueDate

§

Parent

An issue’s direct parent, by selector (WP06 T024).

§

Category

An issue’s resolved workflow category, by category key (WP08 T034).

Derived, not stored. Unlike the nine above, this criterion matches nothing an issue’s file contains: there is no category frontmatter key (research R2), and the value comes from the issue’s status resolved through the board’s category_map. See FilterField::key for what that means for diagnostics.

§

Project

An issue’s project membership, by resolved project id (WP06 T026).

A membership criterion, not a text one. project:<id> asks whether the issue’s association list — Issue::projects, read through the shared crate::projects::ProjectNode::project_ids accessor that ProjectIndex::build itself reads — contains the referenced project. It is deliberately not a substring test on the rendered frontmatter: that would call an issue whose body mentions an id a member, and would match project:p-1 against an issue associated with p-12.

An issue in two projects matches project:A and project:B (recorded in contracts/cli-surface.md §3); an unassociated issue matches no project criterion, and an id no association carries matches nothing.

§

Epic

An issue’s epic membership, by resolved epic id (WP06 T028).

A membership criterion, not a text one, and the exact analogue of FilterField::Project for the epic registry. epic:<id> asks whether the issue’s reference list — Issue::epics, read through the shared crate::epics::EpicNode::epic_ids accessor that crate::epics::EpicIndex::build itself reads — contains the referenced epic. It is deliberately not a substring test on the rendered frontmatter: that would call an issue whose body mentions an id a member, and would match epic:e-1 against an issue referencing e-12.

An issue in two epics matches epic:A and epic:B (recorded in contracts/cli-surface.md §3); an unreferenced issue matches no epic criterion, and an id no reference carries matches nothing.

The token is the singular epic: while Self::key is the plural epics the model serializes — the same split FilterField::Project records, and for the same reason.

Implementations§

Source§

impl FilterField

Source

pub const ALL: [FilterField; 13]

The criteria in modal row order (research D-05).

Parent is appended rather than interleaved: a row’s position is a user’s muscle memory and a TUI test’s golden index, and moving eight existing rows to make room for a ninth helps nobody (T024 step 2).

Category is appended after Parent, for the same reason T024 step 2 gave: a row’s position is a user’s muscle memory and the TUI’s golden index, and it is also the position a user reaches last. A category is the one criterion a user cannot reach from the file itself, so it is the one they will look up last.

Project is appended after Category for the same reason T024 step 2 gave: a row’s position is a user’s muscle memory and the TUI’s golden index. Appending is also what keeps next()/prev() wrapping correct without touching a single existing index — the arithmetic is a modulus of the extended length, and the wrapping test asserts both ends.

Epic is appended after Project (WP06 T028) for exactly the same reason: a row’s position is a user’s muscle memory and the TUI’s golden index, and appending keeps next()/prev() correct as a modulus of the extended length without moving a single existing row.

Source

pub fn label(self) -> &'static str

Source

pub fn key(self) -> &'static str

The serialized frontmatter key each criterion matches against (Issue::to_file_contents emits these). Used by diagnostics.

For FilterField::Category this is the token name, not a frontmatter key, because there is no category key: the criterion is derived from the issue’s status through the board’s category_map (research R2). T034 step 4 asked what to report here and warned that leaving a nonexistent key in the diagnostics would be a quiet lie, so the honest spelling is category — which is exactly what the user types, and what the grammar parses — plus FilterField::is_derived for any surface that has to explain the criterion rather than merely echo it.

The distinction is not cosmetic. key() feeds two things that read very differently: a hint bar, where category:completed is exactly right, and an error, where “no issue has category:completed” would send a user looking for a field that does not exist. [is_derived] is what keeps the second from happening.

Source

pub fn is_derived(self) -> bool

Whether this criterion is derived from other data rather than read off a frontmatter field (WP08 T034 step 4).

Category is the only one. It is derived from status through the board’s category_map, so a diagnostic that names it as a field points at a field that does not exist. Any surface printing why a criterion matched, or why it found nothing, must say so through this.

Source

pub fn describe(self) -> String

The criterion as a user should read it in an explanation: category on its own, or category (derived from status) where the extra clause matters.

Split from [key] so a caller has to choose. A hint bar that appends “(derived from status)” on every keystroke is noise, and an error that omits it sends the user hunting for a field; this hands each surface the short form and lets the ones that explain pick the long one.

Source

pub fn row(self) -> usize

Row index of this criterion in FilterField::ALL.

Source

pub fn next(self) -> Self

Source

pub fn prev(self) -> Self

Source

pub fn value(self, filter: &StructuredFilter) -> Option<&str>

The criterion value when set and non-empty. An empty string is treated as “no criterion” everywhere (canonical invariant), so the filter modal can edit a slot without a live-match surprise.

Source

pub fn value_mut(self, filter: &mut StructuredFilter) -> &mut String

Mutable access to the criterion buffer, materializing an empty one when the criterion is unset (the filter modal types into it and StructuredFilter::normalize promotes empty back to None).

Source

pub fn unset(self, filter: &mut StructuredFilter)

Clear the criterion back to None.

Source

pub fn is_reference(self) -> bool

Whether this criterion is a parent reference rather than a text field.

The distinction drives two things: the free-typing path is bypassed in favour of the issue picker (WP06 T026), and evaluate compares exactly rather than by substring, because a number must not match a longer number that merely contains it.

Source

pub fn token(self) -> &'static str

The criterion’s query token, as the grammar parses it and the hint bar should echo it.

For every criterion but FilterField::Project and FilterField::Epic this is Self::key — the two spellings coincide (status:, labels:, parent: the token and the frontmatter key alike). Those two are the places they differ, and deliberately: the token is the singular project:/epic: the parser accepts and the modal’s help advertises, while the key is the plural projects/epics WP03’s model serializes. A hint bar echoing projects:p-1 would advertise a token query_matches does not parse, which is a key that looks usable and does nothing — the exact failure key()’s own doc warns about for diagnosis.

Source

pub fn is_project(self) -> bool

Whether this criterion is a project membership test rather than a text field (WP06 T026).

Kept separate from Self::is_reference even though both compare exactly: a parent is a number on the issue’s own frontmatter and can be rewritten into the query, while a project is a membership the file’s bytes answer only indirectly (the association list is a YAML block, not a scalar), so the criterion travels in the StructuredFilter and is judged by StructuredFilter::project_matches. The surfaces use this predicate to route the row to the project picker rather than the issue picker.

Source

pub fn is_epic(self) -> bool

Whether this criterion is an epic membership test rather than a text field (WP06 T028).

The exact analogue of Self::is_project: a reference list is a YAML block the rendered bytes answer only indirectly, so the criterion travels in the StructuredFilter and is judged by StructuredFilter::epic_matches. Kept a separate predicate from is_project because the two name different registries and different pickers — collapsing them would make the surfaces offer a project picker for an epic row.

Source

pub fn is_date(self) -> bool

Whether this criterion holds a date (picker-only, no free typing).

Trait Implementations§

Source§

impl Clone for FilterField

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for FilterField

Source§

impl Debug for FilterField

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for FilterField

Source§

impl PartialEq for FilterField

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for FilterField

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.