joker 0.0.5

A JavaScript tokenizer.
Documentation
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct Posn {
    pub offset: u32,
    pub line: u32,
    pub column: u32
}

impl Posn {
    pub fn origin() -> Posn {
        Posn {
            offset: 0,
            line: 0,
            column: 0
        }
    }
}

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct Span {
    pub start: Posn,
    pub end: Posn
}

pub trait TrackingRef {
    fn tracking_ref(&self) -> &Option<Span>;
}

pub trait TrackingMut: TrackingRef {
    fn tracking_mut(&mut self) -> &mut Option<Span>;
}

impl<'a, T: TrackingRef> TrackingRef for &'a T {
    fn tracking_ref(&self) -> &Option<Span> { (*self).tracking_ref() }
}

impl TrackingRef for Option<Span> {
    fn tracking_ref(&self) -> &Option<Span> { self }
}

impl TrackingMut for Option<Span> {
    fn tracking_mut(&mut self) -> &mut Option<Span> { self }
}

pub trait Untrack {
    fn untrack(&mut self);
}

impl<T> Untrack for Box<T>
  where T: Untrack
{
    fn untrack(&mut self) {
        (**self).untrack();
    }
}

impl<T> Untrack for Option<T>
  where T: Untrack
{
    fn untrack(&mut self) {
        match *self {
            Some(ref mut x) => { x.untrack(); }
            None => { }
        }
    }
}

impl<T> Untrack for Vec<T>
  where T: Untrack
{
    fn untrack(&mut self) {
        for x in self {
            x.untrack();
        }
    }
}

pub fn span<T, U>(left: &T, right: &U) -> Option<Span>
  where T: TrackingRef,
        U: TrackingRef
{
    match (*left.tracking_ref(), *right.tracking_ref()) {
        (Some(l), Some(r)) => Some(Span { start: l.start, end: r.end }),
        _ => None
    }
}