use std::fmt::Debug;
use crate::{
error::DijkstraError,
graph::Graph,
node::{NodeId, NodeWeight},
path::Path,
};
pub trait ImplementationStrategy {
type Opts: Debug + Default;
fn run<I: NodeId, W: NodeWeight>(
graph: &Graph<I, W>,
from: I,
to: I,
options: Self::Opts,
) -> Result<Path<I, W>, DijkstraError> {
Err(DijkstraError::StrategyError(format!(
"Strategy not implemented\n[
graph: {:?}
from: {:?}
to: {:?}
opts: {:?}
]",
graph, from, to, options
)))
}
}
pub trait StrategyRunner {
fn strategy<SelectedStrategy: ImplementationStrategy, I: NodeId, W: NodeWeight>(
graph: &Graph<I, W>,
from: I,
to: I,
options: SelectedStrategy::Opts,
) -> Result<Path<I, W>, DijkstraError> {
Strategy::execute_with_opts::<SelectedStrategy, I, W>(graph, from, to, options)
}
}
#[derive(Debug)]
pub struct Strategy {}
impl Strategy {
pub fn execute<SelectedStrategy: ImplementationStrategy, I: NodeId, W: NodeWeight>(
graph: &Graph<I, W>,
from: I,
to: I,
) -> Result<Path<I, W>, DijkstraError> {
SelectedStrategy::run(graph, from, to, SelectedStrategy::Opts::default())
}
pub fn execute_with_opts<SelectedStrategy: ImplementationStrategy, I: NodeId, W: NodeWeight>(
graph: &Graph<I, W>,
from: I,
to: I,
options: SelectedStrategy::Opts,
) -> Result<Path<I, W>, DijkstraError> {
SelectedStrategy::run(graph, from, to, options)
}
}
impl StrategyRunner for Strategy {}
#[cfg(test)]
mod test {
use crate::{
error::DijkstraError,
graph::Graph,
path::Path,
strategy::{ImplementationStrategy, StrategyRunner},
};
#[test]
fn test_strategy() {
#[derive(Debug)]
struct TestStrategy {}
impl ImplementationStrategy for TestStrategy {
type Opts = ();
fn run<I: crate::node::NodeId, W: crate::node::NodeWeight>(
graph: &crate::graph::Graph<I, W>,
from: I,
to: I,
options: Self::Opts,
) -> Result<crate::path::Path<I, W>, DijkstraError> {
Ok(Path::default())
}
}
#[derive(Debug)]
struct TestRunner {}
impl StrategyRunner for TestRunner {}
let path = TestRunner::strategy::<TestStrategy, i32, i32>(&Graph::default(), 0, 99, ());
if let Err(err_msg) = &path {
println!("{}", err_msg.clone());
}
assert_eq!(path.unwrap(), Path::default())
}
}