libtmux Reference MCP Search
On this page

query.Filterable

View as Markdown

Module
query
Package
libtmux
Source
crates/libtmux/src/query.rs
trait query.Filterable
trait [source]
trait [source]
trait query.Filterable

A type with a stable schema that can evaluate portable filter predicates.

This trait is designed for generated implementations; the example spells out that ABI by hand. Methods prefixed with __filter_ are not ordinary authoring hooks.

Examples

use std::error::Error as _;

use libtmux::query::{
    BoolField, EnumField, FilterEnum, FilterExpressionError,
    FilterExpressionErrorKind, Filterable, IntegerField, TextField,
};
use libtmux::query::__private::{self, IntegerKind, Predicate};

enum State {
    Ready,
}

impl FilterEnum for State {
    const FILTER_VARIANTS: &'static [&'static str] = &["ready"];

    fn filter_name(&self) -> &'static str {
        match self {
            Self::Ready => "ready",
        }
    }
}

struct Task {
    name: &'static [u8],
    done: bool,
    priority: i8,
    retries: u8,
    state: State,
}

struct TaskFields {
    name: TextField<Task>,
    done: BoolField<Task>,
    priority: IntegerField<Task, i8>,
    retries: IntegerField<Task, u8>,
    state: EnumField<Task, State>,
}

impl Filterable for Task {
    type Fields = TaskFields;
    const FILTER_TARGET: &'static str = "task";

    fn filter_fields() -> Self::Fields {
        TaskFields {
            name: __private::text_field(Self::FILTER_TARGET, "name"),
            done: __private::bool_field(Self::FILTER_TARGET, "done"),
            priority: __private::integer_field(Self::FILTER_TARGET, "priority"),
            retries: __private::integer_field(Self::FILTER_TARGET, "retries"),
            state: __private::enum_field(Self::FILTER_TARGET, "state"),
        }
    }

    fn __filter_matches(&self, predicate: &Predicate) -> bool {
        Self::__filter_validate(predicate)
            .expect("typed field expressions must validate before matching");
        match predicate.field() {
            "name" => predicate.matches_text(self.name),
            "done" => predicate.matches_bool(self.done),
            "priority" => predicate.matches_signed(i128::from(self.priority)),
            "retries" => predicate.matches_unsigned(u128::from(self.retries)),
            "state" => predicate.matches_enum(self.state.filter_name()),
            _ => false,
        }
    }

    fn __filter_validate(predicate: &Predicate) -> Result<(), FilterExpressionError> {
        match predicate.field() {
            "name" => predicate.validate_text(),
            "done" => predicate.validate_bool(),
            "priority" => predicate.validate_integer(IntegerKind::I8),
            "retries" => predicate.validate_integer(IntegerKind::U8),
            "state" => predicate.validate_enum(State::FILTER_VARIANTS),
            _ => Err(__private::unknown_field_error()),
        }
    }
}

let task = Task {
    name: b"build",
    done: false,
    priority: -1,
    retries: 2,
    state: State::Ready,
};
let fields = Task::filter_fields();
assert!(fields.name.eq("build").matches(&task));
assert!(fields.done.eq(false).matches(&task));
assert!(fields.priority.eq(-1).matches(&task));
assert!(fields.retries.eq(2).matches(&task));
assert!(fields.state.eq(State::Ready).matches(&task));

let error = __private::unknown_field_error();
assert_eq!(error.kind(), FilterExpressionErrorKind::UnknownField);
assert!(error.source().is_none());

Generated relation dispatch uses the same opaque predicate ABI for already-loaded `Vec<T> and Option<T>` fields:

use libtmux::query::{
    BoolField, FilterExpressionError, Filterable, ManyRelation, OneRelation,
};
use libtmux::query::__private::{self, Predicate};

struct Child {
    done: bool,
}

struct ChildFields {
    done: BoolField<Child>,
}

impl Filterable for Child {
    type Fields = ChildFields;
    const FILTER_TARGET: &'static str = "child";

    fn filter_fields() -> Self::Fields {
        ChildFields {
            done: __private::bool_field(Self::FILTER_TARGET, "done"),
        }
    }

    fn __filter_matches(&self, predicate: &Predicate) -> bool {
        assert!(Self::__filter_validate(predicate).is_ok());
        match predicate.field() {
            "done" => predicate.matches_bool(self.done),
            _ => false,
        }
    }

    fn __filter_validate(predicate: &Predicate) -> Result<(), FilterExpressionError> {
        match predicate.field() {
            "done" => predicate.validate_bool(),
            _ => Err(__private::unknown_field_error()),
        }
    }
}

struct Parent {
    children: Vec<Child>,
    favorite: Option<Child>,
}

struct ParentFields {
    children: ManyRelation<Parent, Child>,
    favorite: OneRelation<Parent, Child>,
}

impl Filterable for Parent {
    type Fields = ParentFields;
    const FILTER_TARGET: &'static str = "parent";

    fn filter_fields() -> Self::Fields {
        ParentFields {
            children: __private::many_relation(Self::FILTER_TARGET, "children"),
            favorite: __private::one_relation(Self::FILTER_TARGET, "favorite"),
        }
    }

    fn __filter_matches(&self, predicate: &Predicate) -> bool {
        assert!(Self::__filter_validate(predicate).is_ok());
        match predicate.field() {
            "children" => predicate.matches_many(&self.children),
            "favorite" => predicate.matches_one(self.favorite.as_ref()),
            _ => false,
        }
    }

    fn __filter_validate(predicate: &Predicate) -> Result<(), FilterExpressionError> {
        match predicate.field() {
            "children" => predicate.validate_many::<Child>(),
            "favorite" => predicate.validate_one::<Child>(),
            _ => Err(__private::unknown_field_error()),
        }
    }
}

let parent = Parent {
    children: vec![Child { done: false }, Child { done: true }],
    favorite: Some(Child { done: false }),
};
let parent_fields = Parent::filter_fields();
let child_done = Child::filter_fields().done;
assert!(parent_fields.children.any(child_done.eq(false)).matches(&parent));
assert!(
    parent_fields
        .children
        .all(child_done.is_in([false, true]))
        .matches(&parent)
);
assert!(
    parent_fields
        .children
        .none(child_done.not_in([false, true]))
        .matches(&parent)
);
assert!(parent_fields.favorite.is(child_done.eq(false)).matches(&parent));

0 declared, 0 inherited

Esc

Type to search.