1use crate::buckets::{NUM_BUCKETS_LONG, NUM_BUCKETS_NORMAL, NUM_BUCKETS_SHORT};
7use crate::hash::checksum::{CHECKSUM_SIZE_LONG, CHECKSUM_SIZE_NORMAL};
8use crate::{FuzzyHashType, GeneratorType};
9
10mod private {
12 pub trait SealedVerboseParam {}
14 pub trait SealedParam {}
16 pub trait SealedFuzzyHashes {}
18}
19
20pub struct FuzzyHashParams<const SIZE_CKSUM: usize, const SIZE_BUCKETS: usize>;
22
23pub trait ConstrainedFuzzyHashParams: private::SealedParam {
25 type InnerFuzzyHashType: FuzzyHashType
30 + core::fmt::Debug
31 + core::fmt::Display
32 + Clone
33 + Copy
34 + PartialEq
35 + Eq;
36 type InnerGeneratorType: GeneratorType<Output = Self::InnerFuzzyHashType>
41 + core::fmt::Debug
42 + Default
43 + Clone;
44}
45
46pub trait ConstrainedFuzzyHashType:
48 private::SealedFuzzyHashes
49 + core::fmt::Debug
50 + core::fmt::Display
51 + FuzzyHashType
52 + Clone
53 + PartialEq
54 + Eq
55{
56 type Params: ConstrainedFuzzyHashParams;
58 fn new(inner: <Self::Params as ConstrainedFuzzyHashParams>::InnerFuzzyHashType) -> Self;
60}
61
62pub struct VerboseFuzzyHashParams<
64 const SIZE_CKSUM: usize,
65 const SIZE_BODY: usize,
66 const SIZE_BUCKETS: usize,
67 const SIZE_IN_BYTES: usize,
68 const SIZE_IN_STR_BYTES: usize,
69>;
70
71pub trait ConstrainedVerboseFuzzyHashParams: private::SealedVerboseParam {}
73impl<T> ConstrainedVerboseFuzzyHashParams for T where T: private::SealedVerboseParam {}
74
75macro_rules! param_buckets_desc {
77 (NUM_BUCKETS_SHORT) => {
78 "Short"
79 };
80 (NUM_BUCKETS_NORMAL) => {
81 "Normal"
82 };
83 (NUM_BUCKETS_LONG) => {
84 "Long"
85 };
86}
87
88macro_rules! param_buckets_desc_alt {
90 (NUM_BUCKETS_SHORT) => {
91 "min hash"
92 };
93 (NUM_BUCKETS_NORMAL) => {
94 "compact hash"
95 };
96 (NUM_BUCKETS_LONG) => {
97 "full hash"
98 };
99}
100
101macro_rules! param_checksum_desc {
103 (CHECKSUM_SIZE_NORMAL) => {
104 "1-byte"
105 };
106 (CHECKSUM_SIZE_LONG) => {
107 "3-byte"
108 };
109}
110
111macro_rules! inner_fuzzy_hash_type {
113 ($size_checksum:expr, $size_buckets:tt) => {
114 $crate::hash::inner::FuzzyHash<
115 {$size_checksum},
116 {$size_buckets / 4},
117 {$size_buckets},
118 {$size_buckets / 4 + 2 + $size_checksum},
119 {($size_buckets / 4 + 2 + $size_checksum) * 2 + 2}
120 >
121 };
122}
123
124macro_rules! inner_generator_type {
126 ($size_checksum:expr, $size_buckets:tt) => {
127 $crate::generate::inner::Generator<
128 {$size_checksum},
129 {$size_buckets / 4},
130 {$size_buckets},
131 {$size_buckets / 4 + 2 + $size_checksum},
132 {($size_buckets / 4 + 2 + $size_checksum) * 2 + 2}
133 >
134 };
135}
136
137macro_rules! params {
139 {$($name:ident = ($size_checksum:tt, $size_buckets:tt);)*} => {
140 $(
141 impl private::SealedParam
142 for FuzzyHashParams<{$size_checksum}, {$size_buckets}>
143 {
144 }
145 impl private::SealedVerboseParam
146 for VerboseFuzzyHashParams<
147 {$size_checksum},
148 {$size_buckets / 4},
149 {$size_buckets},
150 {$size_buckets / 4 + 2 + $size_checksum},
151 {($size_buckets / 4 + 2 + $size_checksum) * 2 + 2}
152 >
153 {
154 }
155 impl ConstrainedFuzzyHashParams for FuzzyHashParams<{$size_checksum}, {$size_buckets}> {
156 type InnerFuzzyHashType = inner_fuzzy_hash_type!($size_checksum, $size_buckets);
157 type InnerGeneratorType = inner_generator_type!($size_checksum, $size_buckets);
158 }
159 impl private::SealedFuzzyHashes
160 for crate::hash::FuzzyHash<{$size_checksum}, {$size_buckets}>
161 {
162 }
163 impl ConstrainedFuzzyHashType for crate::hash::FuzzyHash<{$size_checksum}, {$size_buckets}> {
164 type Params = FuzzyHashParams<{$size_checksum}, {$size_buckets}>;
165 fn new(inner: <Self::Params as ConstrainedFuzzyHashParams>::InnerFuzzyHashType) -> Self {
166 Self::new(inner)
167 }
168 }
169 )*
170 pub(crate) mod exported_hashes {
172 use super::*;
173 $(
174 #[doc = concat!(
175 param_buckets_desc!($size_buckets),
176 " fuzzy hash type (",
177 param_buckets_desc_alt!($size_buckets),
178 ") with ",
179 param_checksum_desc!($size_checksum),
180 " checksum.\n",
181 "\n",
182 "For more information about the implementation, see ",
183 "[`FuzzyHashType`](crate::FuzzyHashType).\n",
184 "\n",
185 "For other types with different parameters, ",
186 "see the [module documentation](crate::hashes)."
187 )]
188 pub type $name =
189 crate::hash::FuzzyHash<{$size_checksum}, {$size_buckets}>;
190 )*
191 }
192 };
193}
194params! {
195 Short = (CHECKSUM_SIZE_NORMAL, NUM_BUCKETS_SHORT);
196 Normal = (CHECKSUM_SIZE_NORMAL, NUM_BUCKETS_NORMAL);
197 NormalWithLongChecksum = (CHECKSUM_SIZE_LONG, NUM_BUCKETS_NORMAL);
198 Long = (CHECKSUM_SIZE_NORMAL, NUM_BUCKETS_LONG);
199 LongWithLongChecksum = (CHECKSUM_SIZE_LONG, NUM_BUCKETS_LONG);
200}
201
202mod tests;