On this page
query.Filterable
- Module
- query
- Package
- libtmux
- Source
- crates/libtmux/src/query.rs
-
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>
andOption<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