kaon 0.1.4

A little scripting language written in rust
Documentation
use std::{rc::Rc, fmt};

use crate::common::Source;

#[derive(PartialEq, Hash)]
pub struct Span {
    pub source: Rc<Source>,
    pub start: usize,
    pub length: usize,
}

impl Span {
    pub fn new(start: usize, length: usize, source: &Rc<Source>) -> Self {
        Span {
            start,
            length,
            source: source.clone(),
        }
    }

    pub fn empty() -> Self {
        Span {
            start: 0,
            length: 0,
            source: Source::contents(""),
        }
    }

    pub fn end(&self) -> usize {
        self.start + self.length
    }

    pub fn combine(a: &Span, b: &Span) -> Span {
        let start = a.start.min(b.start);
        let end = a.end().max(b.end());

        let length = end - start;

        Span::new(start, length, &a.source)
    }

    pub fn lines(string: &str) -> Vec<String> {
        string.split('\n').map(|line| line.to_string()).collect()
    }

    pub fn line_index(source: &str, offset: usize) -> (usize, usize) {
        let lines = Span::lines(&source[..offset]);
        let line = lines.len() - 1;
        let col = lines.last().unwrap().chars().count();
        (line, col)
    }
}


impl fmt::Debug for Span {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("{}", self.source.path.to_str().unwrap()))
    }
}

impl Clone for Span {
    fn clone(&self) -> Self {
        Self {
            source: self.source.clone(),
            start: self.start,
            length: self.length,
        }
    }
}

pub struct Spanned<T> {
    pub node: T,
    pub source: Span,
}

impl<T> Spanned<T> {
    pub fn new(node: T, source: Span) -> Spanned<T> {
        Spanned { node, source }
    }
}