//! Build a decision tree from many CSS selectors to quickly find which ones
//! match an HTML element.
//!
//! Given a set of `(selector, value)` pairs, [`DecisionTree`] weaves the
//! selectors into a tree that shares common conditions. Testing one element
//! against the tree takes far fewer checks than testing each selector in turn.
//!
//! The crate does not match against a DOM by itself. It produces an abstract
//! tree. A builder turns that tree into something callable. The built-in
//! [`treeify`] builder renders the tree as text. A DOM plugin builds a
//! [`Picker`] whose matcher walks the tree against a concrete element type.
//!
//! # Supported selectors
//!
//! - Combinators: child `>` and adjacent sibling `+`. Descendant, general
//!   sibling `~`, and column `||` are rejected at build time.
//! - Pseudo-classes: `:empty`, `:first-child`, `:last-child`, `:only-child`,
//!   `:any-link`. Others are rejected at build time.
//! - Attribute values are case-sensitive by default. List attribute names in
//!   [`DecisionTreeOptions::attributes_with_normalized_values`] to make them
//!   case-insensitive by default.
//! - Namespace prefixes such as `svg|` are not honored and are rejected at
//!   build time rather than dropped.
//!
//! # Example
//!
//! ```
//! use selderee::{DecisionTree, DecisionTreeOptions, treeify};
//!
//! let input = vec![
//!     ("foo".to_string(), "value 1".to_string()),
//!     ("bar".to_string(), "value 2".to_string()),
//! ];
//! let tree = DecisionTree::new(input, DecisionTreeOptions::default())?;
//! let text = tree.build(treeify);
//! assert!(text.starts_with("▽\n"));
//! # Ok::<(), selderee::SelectorError>(())
//! ```

#![forbid(unsafe_code)]
#![warn(missing_docs)]

pub mod ast;
mod css;
mod decision_tree;
mod error;
mod ordered_map;
mod picker;
mod treeify;

pub use ast::{
    AttrPredicate, DecisionTreeNode, MatcherNode, Specificity, ValueContainer, VariantNode,
};
pub use css::ast::{Matcher, Modifier};
pub use css::compare_specificity;
pub use decision_tree::{DecisionTree, DecisionTreeOptions};
pub use error::SelectorError;
pub use picker::{pick1_from, MatcherFn, Picker};
pub use treeify::treeify;
