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;