tsukuyomi 0.5.3

Asynchronous Web framework for Rust
Documentation
use {
    failure::Error,
    std::ops::{Index, IndexMut},
};

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub(super) struct ScopeId {
    inner: ScopeIdInner,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum ScopeIdInner {
    Root,
    Index(usize),
}

impl ScopeId {
    pub(super) fn root() -> Self {
        ScopeId {
            inner: ScopeIdInner::Root,
        }
    }
}

#[derive(Debug)]
pub(super) struct Scopes<T> {
    nodes: Vec<Scope<T>>,
    root: Scope<T>,
}

impl<T> Scopes<T> {
    pub(super) fn new(data: T) -> Self {
        Self {
            root: Scope {
                id: ScopeId::root(),
                ancestors: vec![],
                data,
            },
            nodes: vec![],
        }
    }

    pub(super) fn add_node(&mut self, parent: ScopeId, data: T) -> Result<ScopeId, Error> {
        let id = ScopeId {
            inner: ScopeIdInner::Index(self.nodes.len()),
        };

        let parent = &self[parent];

        let mut ancestors = parent.ancestors.clone();
        ancestors.push(parent.id);

        self.nodes.push(Scope {
            id,
            ancestors,
            data,
        });

        Ok(id)
    }
}

impl<T> Index<ScopeId> for Scopes<T> {
    type Output = Scope<T>;

    fn index(&self, id: ScopeId) -> &Self::Output {
        match id.inner {
            ScopeIdInner::Root => &self.root,
            ScopeIdInner::Index(i) => &self.nodes[i],
        }
    }
}

impl<T> IndexMut<ScopeId> for Scopes<T> {
    fn index_mut(&mut self, id: ScopeId) -> &mut Self::Output {
        match id.inner {
            ScopeIdInner::Root => &mut self.root,
            ScopeIdInner::Index(i) => &mut self.nodes[i],
        }
    }
}

#[derive(Debug)]
pub(super) struct Scope<T> {
    id: ScopeId,
    ancestors: Vec<ScopeId>,
    pub(super) data: T,
}

impl<T> Scope<T> {
    pub(super) fn id(&self) -> ScopeId {
        self.id
    }

    pub(super) fn ancestors(&self) -> &[ScopeId] {
        &self.ancestors[..]
    }
}