condor-pathfinding-core 0.4.0

Neutral cross-domain pathfinding primitives shared by Condor algorithm crates.
Documentation
//! Neutral cross-domain primitives shared by Condor owner crates.
//!
//! Holds only lane-agnostic types: continuous [`Point2`] and the search outcome
//! surface in [`search`]. Domain algorithms, scene geometry, grids, and prepared
//! builders stay in their owner crates. The facade re-exports selected items;
//! consumers should prefer `condor` over depending on this crate directly unless
//! they are implementing a domain crate.
//!
//! # Shared outcome vocabulary
//!
//! A valid search can compute either a route or no route; both carry
//! algorithm-defined statistics. Input validation is deliberately separate and
//! remains an outer owner-specific `Result::Err`.
//!
//! ```
//! use condor_core::SearchOutcome;
//!
//! let outcome = SearchOutcome::<&str, usize>::no_path(4);
//! assert!(!outcome.is_found());
//! assert_eq!(outcome.path(), None);
//! assert_eq!(outcome.stats(), &4);
//! ```

#![forbid(unsafe_code)]

/// Optional expansion and wall-clock budgets shared by online search lanes.
pub mod budget;
/// Shared found/no-path outcome vocabulary (stats-bearing, separate from validation `Err`).
pub mod search;

pub use budget::{BudgetExhausted, BudgetWatch, SearchBudget};
pub use search::{SearchOutcome, SearchPathCost, SearchVisitStats};

/// Continuous 2D point in world / scene coordinates (not grid cells).
///
/// Shared by polygonal free-space, any-angle continuous, and navmesh surfaces.
/// Equality is exact `f64` bit identity; geometry epsilon lives in domain crates.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Point2 {
    /// Horizontal world/scene coordinate (same units as domain geometry).
    pub x: f64,
    /// Vertical world/scene coordinate (same units as domain geometry).
    pub y: f64,
}

impl Point2 {
    /// Constructs a 2D point without additional validation.
    #[must_use]
    pub const fn new(x: f64, y: f64) -> Self {
        Self { x, y }
    }

    /// Euclidean distance to `other`.
    #[must_use]
    pub fn distance_to(self, other: Self) -> f64 {
        let dx = self.x - other.x;
        let dy = self.y - other.y;
        (dx * dx + dy * dy).sqrt()
    }
}

impl From<(f64, f64)> for Point2 {
    fn from((x, y): (f64, f64)) -> Self {
        Self::new(x, y)
    }
}