repo_path_macro 1.2.0

Proc_macros for repo_path.
Documentation
use std::path::PathBuf;

use proc_macro::TokenStream;
use quote::quote;
use syn::{ExprLit, Token};


pub(crate) fn parse_path_from_expr_lit(expr_lit: &ExprLit) -> Result<(PathBuf, proc_macro2::Span), syn::Error> {
    match &expr_lit.lit {
        syn::Lit::Str(lit_str) => Ok((PathBuf::from(lit_str.value()), expr_lit.lit.span())),

        _ => Err(syn::Error::new_spanned(expr_lit, "Path needs to be specified as a string.")),
    }
}

pub(crate) fn output_result_as_tokenstream(result: Result<PathBuf, syn::Error>) -> TokenStream {
    let path = match result  {
        Ok(path) => path,
        Err(error) => return error.into_compile_error().into(),
    };

    let path_string = match path.to_str() { //need to convert to string to pass path as token into user-code
        Some(path_string) => path_string,
        None => return quote! {
            compile_error!("Cannot convert string to valid UTF-8.")
        }.into()
    };

    TokenStream::from(quote! {
        ::std::path::PathBuf::from(#path_string)
    })
}

pub(crate) struct CustomPath {
    pub(crate) base_path: ExprLit,
    pub(crate) relative_path: Option<ExprLit>,
}
impl syn::parse::Parse for CustomPath {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {

        let base = input.parse()?;
        let relative = if input.is_empty() {
            None
        } else {
            input.parse::<Token![,]>()?;
            Some(input.parse()?)
        };

        Ok(Self {
            base_path: base,
            relative_path: relative,
        })
    }
}