#![doc(
html_logo_url = "https://raw.githubusercontent.com/arifd/thisversion/main/docs/assets/thisversion.svg",
html_favicon_url = "https://raw.githubusercontent.com/arifd/thisversion/main/docs/assets/thisversion.svg"
)]
#![doc = include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/",
env!("CARGO_PKG_README")
))]
mod boundary;
mod family;
use proc_macro::TokenStream;
use proc_macro_crate::{FoundCrate, crate_name};
use proc_macro2::Span;
use quote::quote;
pub(crate) fn runtime() -> syn::Result<syn::Path> {
match crate_name("thisversion").map_err(|_| {
syn::Error::new(
Span::call_site(),
"could not find the `thisversion` runtime crate; add `thisversion` as a dependency",
)
})? {
FoundCrate::Itself => Ok(syn::parse_quote!(::thisversion)),
FoundCrate::Name(name) => {
let ident = syn::Ident::new(&name, Span::call_site());
Ok(syn::parse2(quote!(::#ident))?)
}
}
}
#[proc_macro_derive(VersionFamily, attributes(thisversion))]
pub fn derive_version_family(input: TokenStream) -> TokenStream {
syn::parse(input)
.and_then(family::parse)
.and_then(|family| Ok((family, runtime()?)))
.map(|(family, runtime)| family::expand(family, &runtime))
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}
#[proc_macro_derive(VersionBoundary, attributes(thisversion))]
pub fn derive_version_boundary(input: TokenStream) -> TokenStream {
syn::parse(input)
.and_then(boundary::parse::parse)
.and_then(|boundary| Ok((boundary, runtime()?)))
.map(|(boundary, runtime)| boundary::expand::expand(boundary, &runtime))
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}