1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
pub mod cardinality;
pub mod max;
pub mod key;
pub mod checksum;

use std::marker::PhantomData;
use std::borrow::Cow;

use Val;
use stash::Location;

pub use meta::cardinality::Cardinality;
pub use meta::checksum::CheckSum;
pub use meta::max::Max;
pub use meta::key::Key;

/// Metadata for `T`
pub trait Meta<T>
    where Self: Clone,
          T: Val
{
    /// Construct a metadata value from `&T`
    fn from_t(t: &T) -> Self;
    // The PhantomData argument seems to be neccesary
    // to have T be in scope in this method.

    /// Merge two metadata values, `(M, M) -> M`
    fn merge(&mut self, other: &Self, _t: PhantomData<T>);
}

/// Implemented for compound-Metadata, for each of the sub-metadatas.
pub trait SubMeta<T>
    where T: Clone
{
    fn submeta(&self) -> Cow<T>;
}

#[derive(Debug)]
pub enum Selection {
    // We found the element
    Hit,
    // We found where the element would have been
    // if it existed (by Ord, or otherwise)
    Between,
    // Not here
    Miss,
}

pub trait Select<T>
    where Self: Sized + Clone
{
    fn select(&mut self, other: Cow<Self>) -> Selection;
}

pub enum Found<T, M>
    where T: Val,
          M: Meta<T>
{
    /// It might be there, but deeper!
    Node(Location<T, M>),
    /// No such thing!
    Miss,
    /// We found it!
    Hit,
    /// If it existed, it would have been here.
    Between,
}