#validation #logic #debugging #quantifiers

quantor

Declarative quantifiers for filtering, validation, and testing in Rust

4 releases (2 breaking)

new 0.10.0 May 18, 2025
0.9.1 May 16, 2025
0.9.0 May 14, 2025
0.1.0 May 4, 2025

#420 in Math

Download history 86/week @ 2025-04-29 38/week @ 2025-05-06 400/week @ 2025-05-13

524 downloads per month

MIT/Apache

70KB
907 lines

quantor

Crates.io Docs.rs Downloads MSRV

Declarative logic for iterators and collections.
quantor lets you express conditions like forall, exists, none, and existsforall directly over data — making filtering, validation, and testing expressive, readable, and idiomatic.

Why quantor?

Rust's iterator methods are powerful, but when you want to write logic that reads like:

  • "All elements are even"
  • "At least one user is active"
  • "Exactly three items matched a condition"

you're often stuck with .all(), .any(), .filter().count(), and some assert! noise.

With quantor, your code becomes declarative and reflects the logic you care about, not the mechanics.

Highlights

  • Quantifiersforall, exists, none, exactly_one, exactly_n, all_equal, pairwise, forallexists, and more.
  • Assertions — Runtime logic assertions like assert_forall!, assert_unique!, assert_pairwise!, with expressive failure output.
  • Predicate-based selection — Filter, deduplicate, or extract based on logic: select_where, select_unique, select_duplicates.
  • Diagnostics — Inspect failing indices, collect mismatches, or integrate with fuzzing tools using QuantorError.
  • Rust-native, ergonomic API – Works with any IntoIterator, zero dependencies, and optional .method() trait extension.

Example & Comparison

If you're validating product data from an online shop:

use quantor::{forall, existsforall, quantify, assert_unique};

#[derive(Debug)]
struct Product {
    id:     u32,
    price:  f64,
    tags:   Vec<&'static str>,
}

#[derive(Debug)]
struct Policy {
    required_tag: &'static str,
}

let products = vec![
    Product { id: 1, price: 19.99, tags: vec!["organic", "new"] },
    Product { id: 2, price: 29.99, tags: vec!["new", "eco"] },
    Product { id: 3, price: 49.99, tags: vec!["premium"] },
];

let policies = vec![
    Policy { required_tag: "new" },
    Policy { required_tag: "eco" },
];

// All quantify!-macro options reside as functions in the quantor crate.

// Each policy must be satisfied by at least one product.
quantify!(forallexists p in &policies, prod in &products =>
    prod.tags.contains(&p.required_tag)
)?;

// At least one product is eco-friendly.
quantify!(exists p in &products => p.tags.contains(&"eco"))?;

// All products are priced.
forall(&products, |p| p.price > 0.0)?;

// IDs are unique.
assert_unique!(&products.iter().map(|p| p.id).collect::<Vec<_>>());

This is readable, declarative, and robust – and every check returns a Result with index-level error diagnostics, while the quantify! macro makes sure you can write conditions comfortably.

Installation

Add quantor to your Cargo.toml:

quantor = "0.10"

Optional features:

  • method-api — Enables .forall(), .exists(), .select_where(), etc. on slices and iterators.
  • debug-tools — Enables debug_assert_* and debug_* macros for non-panicking diagnostics.

📚 Documentation

See docs.rs for full API documentation and examples.

Changelog

See changelog.md for version history.

FAQ

Why does forall return Result<(), QuantorError> instead of bool?
Because failed logical checks are diagnostics, not just false. You get indexed errors and rich messages, not just silent failures.

What’s the difference between select_where and .filter()?
select_where is a semantic wrapper — it describes intent. It’s also easier to reuse and test.

Contributing & Feedback

If quantor made your validation or test code cleaner, I'd love to hear about it.

Have ideas? Open an issue or PR!

No runtime deps

Features