pub struct DnfQuery { /* private fields */ }Expand description
Public query types: a Condition groups into a Conjunction, conjunctions into a DnfQuery.
A query in disjunctive normal form: an OR of Conjunctions.
Construct with DnfQuery::builder or, with the parser feature, with
QueryBuilder::from_query.
§Examples
use dnf::{DnfEvaluable, DnfQuery, Op};
#[derive(DnfEvaluable)]
struct User { age: u32, country: String, premium: bool }
let user = User { age: 30, country: "US".into(), premium: false };
let query = DnfQuery::builder()
.or(|c| c.and("age", Op::GT, 18).and("country", Op::EQ, "US"))
.or(|c| c.and("premium", Op::EQ, true))
.build();
assert!(query.evaluate(&user));Implementations§
Source§impl DnfQuery
impl DnfQuery
Sourcepub fn conjunctions(&self) -> &[Conjunction]
pub fn conjunctions(&self) -> &[Conjunction]
Returns the conjunctions joined by OR.
Sourcepub fn builder() -> QueryBuilder
pub fn builder() -> QueryBuilder
Returns a new QueryBuilder for fluent construction.
Sourcepub fn custom_ops(&self) -> Option<&OpRegistry>
pub fn custom_ops(&self) -> Option<&OpRegistry>
Returns the attached custom-operator registry, or None if none was set.
Sourcepub fn has_custom_op(&self, name: &str) -> bool
pub fn has_custom_op(&self, name: &str) -> bool
Returns true if a custom operator with name is registered.
§Examples
use dnf::{DnfQuery, Op, Value};
let query = DnfQuery::builder()
.with_custom_op("IS_ADULT", true, |f, _| matches!(f, Value::Uint(n) if *n >= 18))
.or(|c| c.and("age", Op::custom("IS_ADULT"), Value::None))
.build();
assert!(query.has_custom_op("IS_ADULT"));
assert!(!query.has_custom_op("MISSING"));Sourcepub fn validate_custom_ops(&self) -> Result<(), DnfError>
pub fn validate_custom_ops(&self) -> Result<(), DnfError>
Verifies every custom operator used in the query is registered.
§Errors
Returns DnfError::UnregisteredCustomOp
for the first condition referencing an operator that has not been
registered.
§Examples
use dnf::{DnfQuery, Op, Value};
let bad = DnfQuery::builder()
.or(|c| c.and("age", Op::custom("IS_SENIOR"), Value::None))
.build();
assert!(bad.validate_custom_ops().is_err());Sourcepub fn evaluate<T: DnfEvaluable>(&self, target: &T) -> bool
pub fn evaluate<T: DnfEvaluable>(&self, target: &T) -> bool
Evaluates the query against a target.
Returns true if any conjunction matches. Short-circuits on the first
matching conjunction; standard operators compare directly without
converting fields to Value, while custom operators convert only the
fields they touch.
§Examples
use dnf::{DnfEvaluable, DnfQuery, Op};
#[derive(DnfEvaluable)]
struct User { age: u32, premium: bool }
let user = User { age: 30, premium: false };
let query = DnfQuery::builder()
.or(|c| c.and("age", Op::GT, 18))
.or(|c| c.and("premium", Op::EQ, true))
.build();
assert!(query.evaluate(&user));Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if the query has no conjunctions and therefore matches nothing.
Sourcepub fn field_names(&self) -> impl Iterator<Item = &str>
pub fn field_names(&self) -> impl Iterator<Item = &str>
Returns an iterator over every field name referenced by the query.
Names appear with duplicates in the order they were added; collect into
a HashSet if you need uniqueness.
§Examples
use dnf::{DnfQuery, Op};
let query = DnfQuery::builder()
.or(|c| c.and("age", Op::GT, 18).and("country", Op::EQ, "US"))
.build();
let names: Vec<_> = query.field_names().collect();
assert_eq!(names, vec!["age", "country"]);Sourcepub fn condition_count(&self) -> usize
pub fn condition_count(&self) -> usize
Returns the total number of conditions across all conjunctions.
§Examples
use dnf::{DnfQuery, Op};
let query = DnfQuery::builder()
.or(|c| c.and("a", Op::EQ, 1).and("b", Op::EQ, 2))
.or(|c| c.and("c", Op::EQ, 3))
.build();
assert_eq!(query.condition_count(), 3);Sourcepub fn uses_field(&self, name: &str) -> bool
pub fn uses_field(&self, name: &str) -> bool
Returns true if any condition references name.
§Examples
use dnf::{DnfQuery, Op};
let query = DnfQuery::builder().or(|c| c.and("age", Op::GT, 18)).build();
assert!(query.uses_field("age"));
assert!(!query.uses_field("name"));Sourcepub fn is_always_false(&self) -> bool
pub fn is_always_false(&self) -> bool
Returns true if the query has no conjunctions and so always evaluates to false.
§Examples
use dnf::DnfQuery;
assert!(DnfQuery::builder().build().is_always_false());Sourcepub fn is_always_true(&self) -> bool
pub fn is_always_true(&self) -> bool
Returns true if any conjunction is empty and so always evaluates to true.
The builder filters empty conjunctions, so a true result here only
happens for queries built via deserialization or internal APIs.
§Examples
use dnf::{DnfQuery, Op};
let q = DnfQuery::builder().or(|c| c.and("age", Op::GT, 18)).build();
assert!(!q.is_always_true());Sourcepub fn validate<T: DnfEvaluable>(self) -> Result<Self, DnfError>
pub fn validate<T: DnfEvaluable>(self) -> Result<Self, DnfError>
Validates field names and custom operators against type T.
§Errors
DnfError::UnknownFieldfor the first condition that references a field not declared byT::fields().DnfError::UnregisteredCustomOpfor the first condition using a custom operator that has not been registered.DnfError::InvalidMapTargetwhen a@keys/@values/at_keyvalue is paired with a non-map field.
§Examples
use dnf::{DnfEvaluable, DnfQuery, Op};
#[derive(DnfEvaluable)]
struct User { age: u32, name: String }
let query = DnfQuery::builder()
.or(|c| c.and("age", Op::GT, 18))
.build()
.validate::<User>()?;Sourcepub fn merge(self, other: Self) -> Self
pub fn merge(self, other: Self) -> Self
Merges another query into this one as an OR combination.
Custom-operator registries from other are merged in; on name collision,
other wins.
§Examples
use dnf::{DnfQuery, Op};
let adults = DnfQuery::builder().or(|c| c.and("age", Op::GTE, 18)).build();
let premium = DnfQuery::builder().or(|c| c.and("premium", Op::EQ, true)).build();
let combined = adults.merge(premium);
assert_eq!(combined.conjunctions().len(), 2);