fera-graph 0.1.1

Graph data structures and algorithms.
Documentation
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::ops::Index;
use std::marker::PhantomData;

trait Map<Key> {
    type Value;

    fn get(&self, key: Key) -> Self::Value;

    fn cloned<'a, T>(&'a self) -> ClonedMap<'a, Self, Key, T>
        where Self: Sized + Map<Key, Value = &'a T>,
              T: 'a
    {
        ClonedMap(self, PhantomData, PhantomData)
    }
}

pub struct ClonedMap<'a, M: 'a, Key, Value: 'a>(&'a M, PhantomData<Key>, PhantomData<Value>);

impl<'a, M, Key, Value> Map<Key> for ClonedMap<'a, M, Key, Value>
    where M: Map<Key, Value = &'a Value>,
          T: Clone
{
    type Value = Value;

    fn get(&self, key: Key) -> Self::Value {
        T::clone(self.0.get(key))
    }
}

pub struct IndexMap<'a, I: 'a>(&'a I);

impl<'a, I, Key> Map<Key> for IndexMap<'a, I>
    where I: 'a + Index<Key>,
          I::Output: 'a
{
    type Value = &'a I::Output;

    fn get(&self, key: Key) -> Self::Value {
        unsafe { ::std::mem::transmute(&self.0[key]) }
    }
}

pub struct ConstMap<'a, T: 'a>(&'a T);

impl<'a, T: 'a> Map<usize> for ConstMap<'a, T> {
    type Value = &'a T;

    fn get(&self, _key: usize) -> Self::Value {
        &self.0
    }
}

#[test]
fn x() {
    let x = 10;
    let c = ConstMap(&x);
    assert_eq!(c.get(2), &x);
    assert_eq!(c.cloned().get(2), x);

    let v = vec![false];
    let c = IndexMap(&v);
    assert_eq!(c.get(0), &false);
    assert_eq!(c.cloned().get(0), false);
}