use std::clone::Clone;
pub struct Context<T> {
pub prev: Option<T>,
pub curr: T,
pub next: Option<T>,
}
impl<'a, T> Context<&'a T> {
pub fn map<U, F>(&self, mut f: F) -> Context<U>
where
F: FnMut(&'a T) -> U,
{
Context {
prev: self.prev.as_ref().map(|t| f(t)),
curr: f(&self.curr),
next: self.next.as_ref().map(|t| f(t)),
}
}
}
impl<'a, T: Clone> Context<&'a T> {
pub fn cloned(&self) -> Context<T> {
self.map(|t| t.clone())
}
}
impl<'a, T> Context<&'a Option<T>> {
pub fn flatten(&self) -> OptContext<&'a T> {
OptContext {
prev: self.prev.and_then(|t| t.as_ref()),
curr: self.curr.as_ref(),
next: self.next.and_then(|t| t.as_ref()),
}
}
}
pub struct OptContext<T> {
pub prev: Option<T>,
pub curr: Option<T>,
pub next: Option<T>,
}
pub struct ItemsInContext<'a, T>
where
T: 'a,
{
slice: &'a [T],
idx: usize,
}
impl<'a, T> Iterator for ItemsInContext<'a, T> {
type Item = Context<&'a T>;
fn next(&mut self) -> Option<Self::Item> {
if self.idx >= self.slice.len() {
None
} else {
let prev = if self.idx == 0 {
None
} else {
self.slice.get(self.idx - 1)
};
let result = Context {
prev: prev,
curr: &self.slice[self.idx],
next: self.slice.get(self.idx + 1),
};
self.idx += 1;
Some(result)
}
}
}
pub trait ItemsInContextExt {
type Item;
fn items_in_context(&self) -> ItemsInContext<Self::Item>;
}
impl<'a, T> ItemsInContextExt for &'a [T] {
type Item = T;
fn items_in_context(&self) -> ItemsInContext<Self::Item> {
ItemsInContext {
slice: self,
idx: 0,
}
}
}
impl<T> ItemsInContextExt for Vec<T> {
type Item = T;
fn items_in_context(&self) -> ItemsInContext<Self::Item> {
ItemsInContext {
slice: &self,
idx: 0,
}
}
}