Documentation
use super::{
    super::{super::cause::*, problem::*},
    r#trait::*,
};

use std::collections::vec_deque::*;

impl ProblemImplementation for Problem {
    fn depth(&self) -> usize {
        self.causes.len()
    }

    fn get(&self, depth: usize) -> Option<&Cause> {
        self.causes.get(depth)
    }

    fn get_mut(&mut self, depth: usize) -> Option<&mut Cause> {
        self.causes.get_mut(depth)
    }

    fn top(&self) -> Option<&Cause> {
        self.causes.front()
    }

    fn top_mut(&mut self) -> Option<&mut Cause> {
        self.causes.front_mut()
    }

    fn root(&self) -> Option<&Cause> {
        self.causes.back()
    }

    fn root_mut(&mut self) -> Option<&mut Cause> {
        self.causes.back_mut()
    }

    fn add_top(&mut self, cause: Cause) {
        self.causes.push_front(cause);
    }

    fn under(mut self, mut problem: Problem) -> Self {
        self.causes.append(&mut problem.causes);
        problem.causes = self.causes;
        problem
    }

    fn above(mut self, mut problem: Problem) -> Self {
        problem.causes.append(&mut self.causes);
        problem
    }
}

impl IntoIterator for Problem {
    type Item = Cause;
    type IntoIter = IntoIter<Cause>;

    fn into_iter(self) -> Self::IntoIter {
        self.causes.into_iter()
    }
}

impl<'this> IntoIterator for &'this Problem {
    type Item = &'this Cause;
    type IntoIter = Iter<'this, Cause>;

    fn into_iter(self) -> Self::IntoIter {
        self.causes.iter()
    }
}

impl<'this> IntoIterator for &'this mut Problem {
    type Item = &'this mut Cause;
    type IntoIter = IterMut<'this, Cause>;

    fn into_iter(self) -> Self::IntoIter {
        self.causes.iter_mut()
    }
}