# Crate ranno

Expand description

Annotations over recursive data structures.

An `Annotation` is a type that annotates a child of a recursive data structure with some extra information. Implementing it for a type allows that type to also be an annotation over a reference to a child.

The `Annotated` type is provided to compute and store the annotation over a reference to a child. Annotations are computed lazily, triggered by when a reference to them is asked for.

## Example

``````extern crate alloc;
use alloc::rc::Rc;

use core::mem;
use ranno::{Annotated, Annotation};

#[derive(Debug, Default, Clone, PartialEq, Eq)]
struct Cardinality(usize);

impl<T> Annotation<LinkedList<T, Cardinality>> for Cardinality {
fn from_child(list: &LinkedList<T, Cardinality>) -> Self {
let c = match list {
LinkedList::Node { next, .. } => 1 + next.anno().0,
};

// the cardinality of a linked list is just the cardinality of the
// next element added to the current one
Self(c)
}
}

enum LinkedList<T, A> {
Empty,
Node {
elem: T,
// the cardinality of a linked list is just the cardinality of the
// next element added to the current one
next: Annotated<Rc<LinkedList<T, A>>, A>,
},
}

impl<T, A> LinkedList<T, A>
where
{
fn new() -> Self {
Self::Empty
}

fn push(&mut self, elem: T) {
let mut next = Self::Empty;
mem::swap(&mut next, self);

let next = Annotated::new(Rc::new(next));
*self = Self::Node { elem, next };
}

fn pop(&mut self) -> Option<T> {
let mut node = Self::Empty;
mem::swap(&mut node, self);

match node {
LinkedList::Node { elem, next } => {
let (next, _) = next.split();
match Rc::try_unwrap(next) {
Ok(list) => {
*self = list;
Some(elem)
}
Err(next) => {
let next = Annotated::new(next);
*self = Self::Node { elem, next };
None
}
}
}
}
}
}

let mut list = LinkedList::<_, Cardinality>::new();

assert_eq!(Cardinality::from_child(&list), Cardinality(0));

list.push(1);
assert_eq!(Cardinality::from_child(&list), Cardinality(1));

list.push(2);
assert_eq!(Cardinality::from_child(&list), Cardinality(2));

list.pop();
assert_eq!(Cardinality::from_child(&list), Cardinality(1));``````

## Structs

A child annotated with some metadata.

A mutable reference to an annotated child.

## Traits

Annotation over a child.