diff options
author | HampusM <hampus@hampusmat.com> | 2022-07-20 14:29:45 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-07-20 14:29:45 +0200 |
commit | 2d1a6b2d432408d74eb57e0bda3f7434617e1070 (patch) | |
tree | 7e21f8126edfdfd9c40b4b51ba5626c6440442d9 /macros/src/libs/intertrait_macros/gen_caster.rs | |
parent | 7863d9859a5cbce99c3769e4fdb40283115d358d (diff) |
refactor: reorganize folder hierarchy
Diffstat (limited to 'macros/src/libs/intertrait_macros/gen_caster.rs')
-rw-r--r-- | macros/src/libs/intertrait_macros/gen_caster.rs | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/macros/src/libs/intertrait_macros/gen_caster.rs b/macros/src/libs/intertrait_macros/gen_caster.rs new file mode 100644 index 0000000..9126200 --- /dev/null +++ b/macros/src/libs/intertrait_macros/gen_caster.rs @@ -0,0 +1,55 @@ +/** + * Originally from Intertrait by CodeChain + * + * <https://github.com/CodeChain-io/intertrait> + * <https://crates.io/crates/intertrait/0.2.2> + * + * Licensed under either of + * + * Apache License, Version 2.0 (LICENSE-APACHE or <http://www.apache.org/licenses/LICENSE-2.0>) + * MIT license (LICENSE-MIT or <http://opensource.org/licenses/MIT>) + + * at your option. +*/ +use std::str::from_utf8_unchecked; + +use proc_macro2::TokenStream; +use quote::format_ident; +use quote::quote; +use quote::ToTokens; +use uuid::adapter::Simple; +use uuid::Uuid; + +pub fn generate_caster(ty: &impl ToTokens, trait_: &impl ToTokens) -> TokenStream +{ + let mut fn_buf = [0u8; FN_BUF_LEN]; + + let fn_ident = format_ident!("{}", new_fn_name(&mut fn_buf)); + + let new_caster = quote! { + syrette::libs::intertrait::Caster::<dyn #trait_>::new( + |from| from.downcast::<#ty>().unwrap(), + |from| from.downcast::<#ty>().unwrap(), + ) + }; + + quote! { + #[syrette::libs::linkme::distributed_slice(syrette::libs::intertrait::CASTERS)] + #[linkme(crate = syrette::libs::linkme)] + fn #fn_ident() -> (::std::any::TypeId, syrette::libs::intertrait::BoxedCaster) { + (::std::any::TypeId::of::<#ty>(), Box::new(#new_caster)) + } + } +} + +const FN_PREFIX: &[u8] = b"__"; +const FN_BUF_LEN: usize = FN_PREFIX.len() + Simple::LENGTH; + +fn new_fn_name(buf: &mut [u8]) -> &str +{ + buf[..FN_PREFIX.len()].copy_from_slice(FN_PREFIX); + Uuid::new_v4() + .to_simple() + .encode_lower(&mut buf[FN_PREFIX.len()..]); + unsafe { from_utf8_unchecked(&buf[..FN_BUF_LEN]) } +} |