hashed_type_def/
lib.rs

1//! This is part of [**Silx**](https://crates.io/crates/silx) project  
2//!   
3//! `hashed-type-def` contains components and macros for deriving, at compile time, type hashcode to identify a type:
4//! * The hashcode is generated as `u128` constant and as `Uuid` constant
5//! * The hashcode generated by the derive macro is built from the morphology of the type definition and does not depend on the rust version  
6//! 
7//! As the crate uses a procedural macro, however, the result could depend on the sequences generated by the parser (`syn`) and therefore on the evolution of this parser
8//! 
9//! # Content
10//! The crate provides two traits `HashedTypeDef` and `HashedTypeMethods`
11//! * the `HashedTypeDef` trait is the basis for defining a type's hashcode
12//!   * It provides constant value of the hashcode under `u128` and `Uuid` formats
13//! * the `HashedTypeMethods` trait provides additional methods for accessing the hashcode  
14//! 
15//! The regular way to implement `HashedTypeDef` is by using the procedural macro `#[derive(HashedTypeDef)]`  
16//! 
17//! The following example gives an overview of `hashed-type-def` features.
18//! 
19//! # Example of type hashcode implementation
20//! ## Cargo.toml
21//! ```toml
22//! [package]
23//! name = "silx_hashed-type-def_examples"
24//! version = "0.1.2"
25//! edition = "2021"
26//! 
27//! [dependencies]
28//! uuid = "1.7.0"
29//! hashed-type-def = { version = "0.1.2", features = ["derive"] }
30//! ```
31//! ## main.rs
32//! ```text
33//! use std::fmt::Debug;
34//! 
35//! use hashed_type_def::{ HashedTypeDef, add_hashed_type_def_param, };
36//! 
37//! /// case 1: a named structure to be tested with procedural derivation
38//! /// * procedural macro `#[derive(HashedTypeDef)]` is the regular way to implement `HashedTypeDef`
39//! #[derive(Debug,HashedTypeDef)]
40//! struct MyStruct<'a,'b,T,U: Debug,const C1: usize, const C2: bool> where T: Into<U> + 'b, 'a: 'b {
41//!     #[allow(dead_code)] un: &'a String,
42//!     #[allow(dead_code)] deux: T,
43//!     #[allow(dead_code)] trois: &'b U,
44//! }
45//! 
46//! pub mod instance0 {
47//!     use hashed_type_def::HashedTypeDef;
48//!     use std::fmt::Debug;
49//! 
50//!     /// case 2: a structure with same definition and procedural derivation as case 1
51//!     /// * type hash should be the same than case 1
52//!     #[derive(Debug,HashedTypeDef)]
53//!     pub struct MyStruct<'a,'b,T,U: Debug,const C1: usize, const C2: bool> where T: Into<U> + 'b, 'a: 'b {
54//!         #[allow(dead_code)] un: &'a String,
55//!         #[allow(dead_code)] deux: T,
56//!         #[allow(dead_code)] trois: &'b U,
57//!     }
58//! } 
59//! 
60//! pub mod instance1 {
61//!     use hashed_type_def::{ add_hashed_type_def, HashedTypeDef, };
62//!     use std::fmt::Debug;
63//!     /// case 3: a structure with same definition as case 1 and post derivation obtained by macro `add_hashed_type_def!` processing on the same definition
64//!     /// * type hash should be the same than case 1
65//!     pub struct MyStruct<'a,'b,T,U: Debug,const C1: usize, const C2: bool> where T: Into<U> + 'b, 'a: 'b {
66//!         #[allow(dead_code)] un: &'a String,
67//!         #[allow(dead_code)] deux: T,
68//!         #[allow(dead_code)] trois: &'b U,
69//!     }
70//! 
71//!     add_hashed_type_def!{
72//!         pub struct MyStruct<'a,'b,T,U: Debug,const C1: usize, const C2: bool> where T: Into<U> + 'b, 'a: 'b {
73//!             un: &'a String,
74//!             deux: T,
75//!             trois: &'b U,
76//!         }    
77//!     }
78//! } 
79//! 
80//! pub mod instance2 {
81//!     use hashed_type_def::HashedTypeDef;
82//!     use std::fmt::Debug;
83//!     /// case 4: a structure with procedural derivation and same definition as case 1 except a swap on lifetime names
84//!     /// * type hash should be different than case 1
85//!     #[derive(Debug,HashedTypeDef)]
86//!     pub struct MyStruct<'b,'a,T,U: Debug,const C1: usize, const C2: bool> where T: Into<U> + 'a, 'b: 'a {
87//!         #[allow(dead_code)] un: &'b String,
88//!         #[allow(dead_code)] deux: T,
89//!         #[allow(dead_code)] trois: &'a U,
90//!     }
91//! } 
92//! 
93//! pub mod instance3 {
94//!     use hashed_type_def::{ add_hashed_type_def, HashedTypeDef, };
95//!     use std::fmt::Debug;
96//!     /// case 5: a structure with same definition as case 1 and post derivation obtained by macro `add_hashed_type_def!` processing on altered definition
97//!     /// * type hash should be different than case 1
98//!     pub struct MyStruct<'a,'b,T,U: Debug,const C1: usize, const C2: bool> where T: Into<U> + 'b, 'a: 'b {
99//!         #[allow(dead_code)] un: &'a String,
100//!         #[allow(dead_code)] deux: T,
101//!         #[allow(dead_code)] trois: &'b U,
102//!     }
103//! 
104//!     add_hashed_type_def!{
105//!         pub struct MyStruct<'a,'b,T,U: Debug,const C1: usize, const C2: bool> where T: Into<U> + 'b, 'a: 'b {
106//!             instance3_MyStruct: (),
107//!             un: &'a String,
108//!             deux: T,
109//!             trois: &'b U,
110//!         }    
111//!     }
112//! } 
113//! 
114//! pub mod instance4 {
115//!     use hashed_type_def::HashedTypeDef;
116//!     use std::fmt::Debug;
117//!     /// case 6: a structure with procedural derivation and same definition as case 1 except conditions are moved to where clauses
118//!     /// * type hash should be different than case 1
119//!     #[derive(Debug,HashedTypeDef)]
120//!     pub struct MyStruct<'a,'b,T,U,const C1: usize, const C2: bool> where 'a: 'b, T: Into<U> + 'b, U: Debug, {
121//!         #[allow(dead_code)] un: &'a String,
122//!         #[allow(dead_code)] deux: T,
123//!         #[allow(dead_code)] trois: &'b U,
124//!     }
125//! } 
126//! 
127//! pub mod instance5 {
128//!     use hashed_type_def::HashedTypeDef;
129//!     use std::fmt::Debug;
130//!     /// case 7: a structure with procedural derivation and same definition as case 1 except conditions are moved from where clauses
131//!     /// * type hash should be different than case 1
132//!     #[derive(Debug,HashedTypeDef)]
133//!     pub struct MyStruct<'a: 'b,'b, T: Into<U> + 'b, U: Debug, const C1: usize, const C2: bool> {
134//!         #[allow(dead_code)] un: &'a String,
135//!         #[allow(dead_code)] deux: T,
136//!         #[allow(dead_code)] trois: &'b U,
137//!     }
138//! } 
139//! 
140//! pub mod instance6 {
141//!     use hashed_type_def::HashedTypeDef;
142//!     use std::fmt::Debug;
143//!     /// case 8: a structure with procedural derivation and same definition as case 1 except a conditions is removed from parameters list
144//!     /// * type hash should be different than case 1    
145//!     #[derive(Debug,HashedTypeDef)]
146//!     pub struct MyStruct<'a,'b,T,U,const C1: usize, const C2: bool> where T: Into<U> + 'b, 'a: 'b {
147//!         #[allow(dead_code)] un: &'a String,
148//!         #[allow(dead_code)] deux: T,
149//!         #[allow(dead_code)] trois: &'b U,
150//!     }
151//! } 
152//! 
153//! pub mod instance7 {
154//!     use hashed_type_def::HashedTypeDef;
155//!     use std::fmt::Debug;
156//!     /// case 9: a structure with procedural derivation and same definition as case 1 except a condition is removed from where clauses
157//!     /// * type hash should be different than case 1
158//!     #[derive(Debug,HashedTypeDef)]
159//!     pub struct MyStruct<'a,'b,T,U: Debug,const C1: usize, const C2: bool> where T: Into<U> + 'b, {
160//!         #[allow(dead_code)] un: &'a String,
161//!         #[allow(dead_code)] deux: T,
162//!         #[allow(dead_code)] trois: &'b U,
163//!     }
164//! } 
165//! 
166//! /// build type hash (Uuid format) of case 1 for specific lifetime
167//! /// * type hash should not change
168//! fn fn_type_hash<'a: 'b,'b>(_tmp1: &'a (), _tmp2: &'b ()) -> uuid::Uuid { MyStruct::<'a,'b,f32,f64,12,true>::UUID }
169//! 
170//! /// case 10: a unnamed structure to be tested with procedural derivation
171//! #[derive(Debug,HashedTypeDef)]
172//! struct MyTupleStruct<T,U: Debug>(String,T,U,) where T: Into<U>;
173//! 
174//! /// case 11: a unit structure to be tested with procedural derivation
175//! #[derive(Debug,HashedTypeDef)]
176//! struct MyEmptyStruct;
177//! 
178//! /// case 12: enum to be tested with procedural derivation
179//! #[derive(Debug,HashedTypeDef)]
180//! enum MyEnum<T,U: Debug> where T: Into<U> {
181//!     #[allow(dead_code)] Zero,
182//!     #[allow(dead_code)] Un(String, T,),
183//!     #[allow(dead_code)] Deux {
184//!         double: f64,
185//!         trois: U,
186//!     },
187//!     #[allow(dead_code)] Trois,
188//! }
189//! 
190//! /// case 13: empty enum to be tested with procedural derivation
191//! #[derive(Debug,HashedTypeDef)]
192//! enum MyEmptyEnum { }
193//! 
194//! /// case 14: a struct to be tested with post derivation with parameter tag `(Option<u32>,[u128;24])`
195//! struct AnotherStruct<T: Debug> where T: Default { #[allow(dead_code)] t: T }
196//! 
197//! add_hashed_type_def_param!((Option<u32>,[u128;24]); struct AnotherStruct<T: Debug> where T: Default { t: T });
198//! 
199//! /// Different cases of type hash derivation
200//! fn main() {
201//!     // case 1 with `true` parameter
202//!     println!("MyStruct::<'static,'static,f32,f64,12,true>::UUID -> {:x}", MyStruct::<'static,'static,f32,f64,12,true>::UUID);
203//!     // case 1 with `true` parameter and different lifetime
204//!     println!("MyStruct::<'a,'b,f32,f64,12,true>::UUID -> {:x}", { let a = (); { let b = (); fn_type_hash(&a,&b) } });
205//!     // case 1 with `false` parameter
206//!     println!("MyStruct::<'static,'static,f32,f64,12,false>::UUID -> {:x}", MyStruct::<'static,'static,f32,f64,12,false>::UUID);
207//!     // case 2 with `false` parameter
208//!     println!("instance0::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> {:x}", instance0::MyStruct::<'static,'static,f32,f64,12,false>::UUID);
209//!     // case 3 with `false` parameter
210//!     println!("instance1::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> {:x}", instance1::MyStruct::<'static,'static,f32,f64,12,false>::UUID);
211//!     // case 4 with `false` parameter
212//!     println!("instance2::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> {:x}", instance2::MyStruct::<'static,'static,f32,f64,12,false>::UUID);
213//!     // case 5 with `false` parameter
214//!     println!("instance3::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> {:x}", instance3::MyStruct::<'static,'static,f32,f64,12,false>::UUID);
215//!     // case 6 with `false` parameter
216//!     println!("instance4::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> {:x}", instance4::MyStruct::<'static,'static,f32,f64,12,false>::UUID);
217//!     // case 7 with `false` parameter
218//!     println!("instance5::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> {:x}", instance5::MyStruct::<'static,'static,f32,f64,12,false>::UUID);
219//!     // case 8 with `false` parameter
220//!     println!("instance6::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> {:x}", instance6::MyStruct::<'static,'static,f32,f64,12,false>::UUID);
221//!     // case 9 with `false` parameter
222//!     println!("instance7::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> {:x}", instance7::MyStruct::<'static,'static,f32,f64,12,false>::UUID);
223//!     // case 10
224//!     println!("MyTupleStruct::<f32,f64>::UUID -> {:x}", MyTupleStruct::<f32,f64>::UUID);
225//!     // case 11
226//!     println!("MyEmptyStruct::UUID -> {:x}", MyEmptyStruct::UUID);
227//!     // case 12
228//!     println!("MyEnum::<f32,f64,>::UUID -> {:x}", MyEnum::<f32,f64,>::UUID);
229//!     // case 13
230//!     println!("MyEmptyEnum::UUID -> {:x}", MyEmptyEnum::UUID);
231//!     // case 14
232//!     println!("AnotherStruct::<Vec<u16>>::UUID -> {:x}", AnotherStruct::<Vec<u16>>::UUID);
233//! }
234//! ```
235//! ## Typical output
236//! ```txt
237//! MyStruct::<'static,'static,f32,f64,12,true>::UUID -> bd84ac66-d0fa-5d1c-ae5e-25647a13dcb3
238//! MyStruct::<'a,'b,f32,f64,12,true>::UUID -> bd84ac66-d0fa-5d1c-ae5e-25647a13dcb3
239//! MyStruct::<'static,'static,f32,f64,12,false>::UUID -> 1a8a7365-1c9c-afed-cca3-983399a91fd8
240//! instance0::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> 1a8a7365-1c9c-afed-cca3-983399a91fd8
241//! instance1::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> 1a8a7365-1c9c-afed-cca3-983399a91fd8
242//! instance2::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> bbe982ff-fcad-5390-86f0-cce2e7dbae6b
243//! instance3::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> 56d4f1b7-af31-d361-3afb-dc89e52c2ded
244//! instance4::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> 394096e5-5187-edf4-ac77-3f6edc052b72
245//! instance5::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> e7e26201-4095-31d1-bfa3-fd4b62abc938
246//! instance6::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> 0bee6197-ef3e-a446-890a-c34705c30cdd
247//! instance7::MyStruct::<'static,'static,f32,f64,12,false>::UUID -> f8f3fcc7-e4a5-e021-e200-763b4cf9df7a
248//! MyTupleStruct::<f32,f64>::UUID -> ddd04a26-6807-0f27-67b2-227db8f17b75
249//! MyEmptyStruct::UUID -> 4ede75e3-1bf7-5298-ae87-0ee1d57a1357
250//! MyEnum::<f32,f64,>::UUID -> fcad4ca3-6cd0-6c7e-21ea-658a12369d9f
251//! MyEmptyEnum::UUID -> 9dec7519-c5f4-12b9-0509-b5b2ef1d521c
252//! AnotherStruct::<Vec<u16>>::UUID -> 933ae311-b69a-f600-7caa-030743cbb5e5
253//! ```
254
255
256pub use hashed_type_def_core::{ HashedTypeDef, HashedTypeMethods, add_hash_fnv1a, start_hash_fnv1a, };
257#[allow(deprecated)]
258pub use hashed_type_def_core::HashedTypeUuid;
259#[cfg(feature = "derive")]
260#[allow(unused_imports)]
261#[macro_use]
262extern crate hashed_type_def_procmacro;
263
264#[cfg(feature = "derive")]
265#[doc(hidden)]
266pub use hashed_type_def_procmacro::{ HashedTypeDef, add_hashed_type_def, add_hashed_type_def_param, };
267
268#[doc(hidden)]
269/// Probes for testing features activation
270pub mod probes;