inktree 0.1.0

An incremental syntax tree engine for fast, expressive language tooling in Rust
Documentation
use std::fmt::Display;

use proc_macro2::TokenStream;
use snafu::AsErrorSource;

#[derive(Debug)]
pub struct Errors<E>(pub Vec<E>)
where
    E: std::error::Error;

impl<E> Errors<E>
where
    E: std::error::Error + 'static,
{
    pub fn into_compile_errors(self) -> Vec<proc_macro2::TokenStream> {
        fn find_source(mut error: &(dyn std::error::Error + 'static)) -> TokenStream {
            while !error.is::<syn::Error>() {
                error = error.source().expect("no error source")
            }
            let span = error
                .downcast_ref::<syn::Error>()
                .expect("downcast error")
                .span();
            syn::Error::new(span, format!("{}", error)).into_compile_error()
        }
        self.0
            .into_iter()
            .map(|err| find_source(err.as_error_source()))
            .collect()
    }
    pub fn map_errors<T: snafu::Error + std::convert::From<E>>(self) -> Errors<T> {
        self.0.into_iter().map(T::from).collect()
    }
}

impl<T> From<T> for Errors<T>
where
    T: snafu::Error,
{
    fn from(value: T) -> Self {
        Self(vec![value])
    }
}

impl<T, U> FromIterator<T> for Errors<U>
where
    U: snafu::Error,
    U: From<T>,
{
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
        Self(Vec::from_iter(iter.into_iter().map(|val| U::from(val))))
    }
}

impl<E> Into<Vec<E>> for Errors<E>
where
    E: std::error::Error,
{
    fn into(self) -> Vec<E> {
        self.0
    }
}

impl<E> Display for Errors<E>
where
    E: std::error::Error,
{
    fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        todo!("format")
    }
}

impl<E: std::error::Error> From<Vec<E>> for Errors<E> {
    fn from(value: Vec<E>) -> Self {
        Self(value)
    }
}

impl<E: std::error::Error> std::error::Error for Errors<E> {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        None
    }

    fn description(&self) -> &str {
        "description() is deprecated; use Display"
    }

    fn cause(&self) -> Option<&dyn std::error::Error> {
        self.source()
    }
}