use iter::{RecurseObjects, RecurseData};
pub enum NodeState<O, C> {
Empty,
Leaf(O),
Branch(C),
}
pub trait Node {
type Partition;
type Object;
type Container;
fn state(&self) -> NodeState<&Self::Object, &Self::Container>;
fn partition(&self) -> Self::Partition;
}
pub trait AssociatedData {
type Data;
fn data(&self) -> &Self::Data;
}
pub trait ObjectQuery: Node + Sized {
fn query_objects<'a, R>(&'a self, recurse: R) -> RecurseObjects<'a, Self, R>
where R: Fn(&Self) -> bool;
}
impl<T> ObjectQuery for T
where T: Node<Container = Vec<T>>,
{
fn query_objects<'a, R>(&'a self, recurse: R) -> RecurseObjects<'a, Self, R>
where R: Fn(&T) -> bool
{
RecurseObjects::new(self, recurse)
}
}
pub trait DataQuery: AssociatedData + Sized {
fn query_data<'a, R>(&'a self, recurse: R) -> RecurseData<'a, Self, R>
where R: Fn(&Self) -> bool;
}
impl<T> DataQuery for T
where T: Node<Container=Vec<T>> + AssociatedData,
{
fn query_data<'a, R>(&'a self, recurse: R) -> RecurseData<'a, T, R>
where R: Fn(&Self) -> bool
{
RecurseData::new(self, recurse)
}
}
pub trait Position {
type Point;
fn position(&self) -> Self::Point;
}
impl<'a, O> Position for &'a O
where O: Position
{
type Point = <O as Position>::Point;
fn position(&self) -> <O as Position>::Point {
(*self).position()
}
}
#[derive(Clone)]
pub struct Positioned<O, P> {
pub object: O,
pub position: P,
}
impl<O, P> Position for Positioned<O, P>
where P: Copy
{
type Point = P;
fn position(&self) -> P {
self.position
}
}
#[cfg(test)]
mod test {
use super::{Position, Positioned};
#[test]
fn positioned_position() {
assert_eq!(Positioned { object: (), position: 14 }.position(), 14);
}
#[test]
fn positionable_by_ref() {
fn twice_pos<O: Position<Point=i32>>(obj: O) -> i32 {
2 * obj.position()
}
let obj = Positioned { object: (), position: 77 };
assert_eq!(twice_pos(&obj), 154);
}
}