use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
use syn::Result;
pub fn core_path() -> Result<TokenStream> {
let package = "ddd-toolkit-core";
if let Ok(found) = proc_macro_crate::crate_name(package)
&& let Some(path) = path_for_found_crate(package, found)
{
return Ok(path);
}
Err(syn::Error::new(
Span::call_site(),
"DDD derives require a ddd or ddd-core dependency",
))
}
fn path_for_found_crate(package: &str, found: proc_macro_crate::FoundCrate) -> Option<TokenStream> {
match found {
proc_macro_crate::FoundCrate::Itself if package == "ddd" => None,
proc_macro_crate::FoundCrate::Itself => {
let ident = Ident::new(&package.replace('-', "_"), Span::call_site());
Some(quote!(::#ident))
}
proc_macro_crate::FoundCrate::Name(name) => {
let ident = Ident::new(&name, Span::call_site());
Some(quote!(::#ident))
}
}
}
#[cfg(test)]
mod tests {
use super::path_for_found_crate;
use proc_macro_crate::FoundCrate;
#[test]
fn skips_facade_itself_and_falls_back_to_core() {
assert!(path_for_found_crate("ddd", FoundCrate::Itself).is_none());
assert_eq!(
path_for_found_crate("ddd-core", FoundCrate::Itself)
.unwrap()
.to_string(),
":: ddd_core"
);
}
#[test]
fn preserves_renamed_facade_dependency() {
assert_eq!(
path_for_found_crate("ddd", FoundCrate::Name("facade".into()))
.unwrap()
.to_string(),
":: facade"
);
}
}