use std::sync::Arc;
use crate::transition::{MatchError, RoutedPath};
use crate::{PredicateCache, SolverVariant};
use geo::LineString;
use routers_network::{Entry, Metadata, Network};
pub const DEFAULT_SEARCH_DISTANCE: f64 = 50.0;
pub struct MatchOptions<E: Entry, M: Metadata, N: Network<E, M>> {
pub search_distance: f64,
pub runtime: M::Runtime,
pub solver: SolverVariant,
pub cache: Option<Arc<PredicateCache<E, M, N>>>,
}
impl<E: Entry, M: Metadata, N: Network<E, M>> Default for MatchOptions<E, M, N> {
fn default() -> Self {
Self {
search_distance: DEFAULT_SEARCH_DISTANCE,
runtime: M::default_runtime(),
solver: SolverVariant::default(),
cache: None,
}
}
}
impl<E: Entry, M: Metadata, N: Network<E, M>> MatchOptions<E, M, N> {
pub fn new() -> Self {
Self::default()
}
pub fn with_runtime(self, runtime: M::Runtime) -> Self {
Self { runtime, ..self }
}
pub fn with_cache(self, cache: Arc<PredicateCache<E, M, N>>) -> Self {
Self {
cache: Some(cache),
..self
}
}
pub fn with_solver(self, solver: impl Into<SolverVariant>) -> Self {
Self {
solver: solver.into(),
..self
}
}
pub fn with_search_distance(self, search_distance: Option<f64>) -> Self {
Self {
search_distance: search_distance.unwrap_or(self.search_distance),
..self
}
}
}
pub trait Match<E, M, N>
where
E: Entry,
M: Metadata,
N: Network<E, M>,
{
fn r#match(
&self,
linestring: LineString,
opts: MatchOptions<E, M, N>,
) -> Result<RoutedPath<E, M>, MatchError>;
fn snap(
&self,
linestring: LineString,
opts: MatchOptions<E, M, N>,
) -> Result<RoutedPath<E, M>, MatchError>;
}
pub trait MatchSimpleExt<E, M, N>: Match<E, M, N>
where
E: Entry,
M: Metadata,
N: Network<E, M>,
{
fn r#match_simple(&self, linestring: LineString) -> Result<RoutedPath<E, M>, MatchError> {
self.r#match(linestring, MatchOptions::default())
}
fn snap_simple(&self, linestring: LineString) -> Result<RoutedPath<E, M>, MatchError> {
self.snap(linestring, MatchOptions::default())
}
}
impl<T, E: Entry, M: Metadata, N: Network<E, M>> MatchSimpleExt<E, M, N> for T where
T: Match<E, M, N>
{
}