use crate::buckets::{NUM_BUCKETS_LONG, NUM_BUCKETS_NORMAL, NUM_BUCKETS_SHORT};
use crate::hash::checksum::{CHECKSUM_SIZE_LONG, CHECKSUM_SIZE_NORMAL};
use crate::{FuzzyHashType, GeneratorType};
mod private {
pub trait SealedVerboseParam {}
pub trait SealedParam {}
pub trait SealedFuzzyHashes {}
}
pub struct FuzzyHashParams<const SIZE_CKSUM: usize, const SIZE_BUCKETS: usize>;
pub trait ConstrainedFuzzyHashParams: private::SealedParam {
type InnerFuzzyHashType: FuzzyHashType
+ core::fmt::Debug
+ core::fmt::Display
+ Clone
+ Copy
+ PartialEq
+ Eq;
type InnerGeneratorType: GeneratorType<Output = Self::InnerFuzzyHashType>
+ core::fmt::Debug
+ Default
+ Clone;
}
pub trait ConstrainedFuzzyHashType:
private::SealedFuzzyHashes
+ core::fmt::Debug
+ core::fmt::Display
+ FuzzyHashType
+ Clone
+ PartialEq
+ Eq
{
type Params: ConstrainedFuzzyHashParams;
fn new(inner: <Self::Params as ConstrainedFuzzyHashParams>::InnerFuzzyHashType) -> Self;
}
pub struct VerboseFuzzyHashParams<
const SIZE_CKSUM: usize,
const SIZE_BODY: usize,
const SIZE_BUCKETS: usize,
const SIZE_IN_BYTES: usize,
const SIZE_IN_STR_BYTES: usize,
>;
pub trait ConstrainedVerboseFuzzyHashParams: private::SealedVerboseParam {}
impl<T> ConstrainedVerboseFuzzyHashParams for T where T: private::SealedVerboseParam {}
macro_rules! param_buckets_desc {
(NUM_BUCKETS_SHORT) => {
"Short"
};
(NUM_BUCKETS_NORMAL) => {
"Normal"
};
(NUM_BUCKETS_LONG) => {
"Long"
};
}
macro_rules! param_buckets_desc_alt {
(NUM_BUCKETS_SHORT) => {
"min hash"
};
(NUM_BUCKETS_NORMAL) => {
"compact hash"
};
(NUM_BUCKETS_LONG) => {
"full hash"
};
}
macro_rules! param_checksum_desc {
(CHECKSUM_SIZE_NORMAL) => {
"1-byte"
};
(CHECKSUM_SIZE_LONG) => {
"3-byte"
};
}
macro_rules! inner_fuzzy_hash_type {
($size_checksum:expr, $size_buckets:tt) => {
$crate::hash::inner::FuzzyHash<
{$size_checksum},
{$size_buckets / 4},
{$size_buckets},
{$size_buckets / 4 + 2 + $size_checksum},
{($size_buckets / 4 + 2 + $size_checksum) * 2 + 2}
>
};
}
macro_rules! inner_generator_type {
($size_checksum:expr, $size_buckets:tt) => {
$crate::generate::inner::Generator<
{$size_checksum},
{$size_buckets / 4},
{$size_buckets},
{$size_buckets / 4 + 2 + $size_checksum},
{($size_buckets / 4 + 2 + $size_checksum) * 2 + 2}
>
};
}
macro_rules! params {
{$($name:ident = ($size_checksum:tt, $size_buckets:tt);)*} => {
$(
impl private::SealedParam
for FuzzyHashParams<{$size_checksum}, {$size_buckets}>
{
}
impl private::SealedVerboseParam
for VerboseFuzzyHashParams<
{$size_checksum},
{$size_buckets / 4},
{$size_buckets},
{$size_buckets / 4 + 2 + $size_checksum},
{($size_buckets / 4 + 2 + $size_checksum) * 2 + 2}
>
{
}
impl ConstrainedFuzzyHashParams for FuzzyHashParams<{$size_checksum}, {$size_buckets}> {
type InnerFuzzyHashType = inner_fuzzy_hash_type!($size_checksum, $size_buckets);
type InnerGeneratorType = inner_generator_type!($size_checksum, $size_buckets);
}
impl private::SealedFuzzyHashes
for crate::hash::FuzzyHash<{$size_checksum}, {$size_buckets}>
{
}
impl ConstrainedFuzzyHashType for crate::hash::FuzzyHash<{$size_checksum}, {$size_buckets}> {
type Params = FuzzyHashParams<{$size_checksum}, {$size_buckets}>;
fn new(inner: <Self::Params as ConstrainedFuzzyHashParams>::InnerFuzzyHashType) -> Self {
Self::new(inner)
}
}
)*
pub(crate) mod exported_hashes {
use super::*;
$(
#[doc = concat!(
param_buckets_desc!($size_buckets),
" fuzzy hash type (",
param_buckets_desc_alt!($size_buckets),
") with ",
param_checksum_desc!($size_checksum),
" checksum.\n",
"\n",
"For more information about the implementation, see ",
"[`FuzzyHashType`](crate::FuzzyHashType).\n",
"\n",
"For other types with different parameters, ",
"see the [module documentation](crate::hashes)."
)]
pub type $name =
crate::hash::FuzzyHash<{$size_checksum}, {$size_buckets}>;
)*
}
};
}
params! {
Short = (CHECKSUM_SIZE_NORMAL, NUM_BUCKETS_SHORT);
Normal = (CHECKSUM_SIZE_NORMAL, NUM_BUCKETS_NORMAL);
NormalWithLongChecksum = (CHECKSUM_SIZE_LONG, NUM_BUCKETS_NORMAL);
Long = (CHECKSUM_SIZE_NORMAL, NUM_BUCKETS_LONG);
LongWithLongChecksum = (CHECKSUM_SIZE_LONG, NUM_BUCKETS_LONG);
}
mod tests;