-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generics are now supported in Macros
- Loading branch information
1 parent
2562066
commit 230f0f3
Showing
10 changed files
with
151 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use std::collections::hash_map::DefaultHasher; | ||
use std::hash::Hash; | ||
use digestible::Digestible; | ||
|
||
#[derive(Digestible)] | ||
#[digestible(hash = LittleEndian)] | ||
pub struct MyStructGenerics<T> { | ||
pub id: u32, | ||
pub t: T, | ||
} | ||
#[derive(Digestible)] | ||
pub struct MyStructGenericsAlreadyRequired<T: Digestible> { | ||
pub id: u32, | ||
pub t: T, | ||
} | ||
|
||
#[test] | ||
pub fn hash_test() { | ||
let test = MyStructGenerics { | ||
id: 0, | ||
t: "Test".to_string(), | ||
}; | ||
let mut default_hasher = DefaultHasher::new(); | ||
test.hash(&mut default_hasher); | ||
} | ||
|
||
|
||
#[derive(Digestible)] | ||
pub enum MyEnum<T> { | ||
A(T), | ||
B(u32), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
use proc_macro2::{Ident, TokenStream}; | ||
use syn::{GenericParam, Generics, ImplGenerics, parse_quote, Path, TypeGenerics, WhereClause}; | ||
|
||
pub fn digestible_path() -> Path { | ||
parse_quote!(_digestible::Digestible) | ||
} | ||
pub fn digest_writer() -> Path { | ||
parse_quote!(_digestible::DigestWriter) | ||
} | ||
pub fn digest_with_path(path: Path) -> Path { | ||
parse_quote!(_digestible::digest_with::#path) | ||
} | ||
pub fn digester_using_hasher() -> Path { | ||
parse_quote!(_digestible::hash_digester::DigesterUsingHasher) | ||
} | ||
|
||
pub fn byte_order_path() -> Path { | ||
parse_quote!(_digestible::byteorder::ByteOrder) | ||
} | ||
pub fn byte_order_impl_path(ident: Ident) -> Path { | ||
parse_quote!(_digestible::byteorder::#ident) | ||
} | ||
|
||
macro_rules! private_path { | ||
// `()` indicates that the macro takes no argument. | ||
($key:ident) => { | ||
syn::parse_quote!(_digestible::_private::$key) | ||
}; | ||
} | ||
pub(crate) use private_path; | ||
|
||
pub fn add_digestible_trait(generics: &mut Generics) { | ||
if generics.params.is_empty() { | ||
return; | ||
} | ||
for param in &mut generics.params { | ||
if let GenericParam::Type(ty) = param { | ||
ty.bounds.push(parse_quote!(_digestible::Digestible)); | ||
} | ||
} | ||
} | ||
|
||
use quote::quote; | ||
|
||
/// Implements `Hash` for the container. | ||
/// Using Digestible | ||
pub fn impl_hash(container: &Ident, endian_path: Path, impl_generics: &ImplGenerics, ty_generics: &TypeGenerics, where_clause: &Option<&WhereClause>) -> TokenStream { | ||
let digester_using_hasher = digester_using_hasher(); | ||
let digestible_path = digestible_path(); | ||
let hash: Path = private_path!(Hash); | ||
let hasher: Path = private_path!(Hasher); | ||
quote! { | ||
#[automatically_derived] | ||
impl #impl_generics #hash for #container #ty_generics #where_clause { | ||
fn hash<H: #hasher>(&self, state: &mut H) { | ||
let mut digester = #digester_using_hasher(state); | ||
<Self as #digestible_path>::digest::<#endian_path, _>(self,&mut digester); | ||
} | ||
} | ||
} | ||
} |