use std::num::ParseIntError;
use assembly_fdb_core::{
value::{owned::Field, Context, Value, ValueType},
FdbHash,
};
use displaydoc::Display;
use thiserror::Error;
#[derive(Debug, Clone)]
pub struct PrimaryKeyFilter {
hash_value: u32,
value: Field,
}
impl PrimaryKeyFilter {
pub fn hash(&self) -> u32 {
self.hash_value
}
pub fn original(&self) -> &Field {
&self.value
}
pub fn filter<C: Context>(&self, other: &Value<C>) -> bool
where
Field: PartialEq<Value<C>>,
{
&self.value == other
}
pub fn integer(value: i32) -> Self {
Self {
hash_value: FdbHash::hash(&value),
value: Field::Integer(value),
}
}
pub fn bigint(value: i64) -> Self {
Self {
hash_value: FdbHash::hash(&value),
value: Field::BigInt(value),
}
}
pub fn text(value: String) -> Self {
Self {
hash_value: FdbHash::hash(&value),
value: Field::Text(value),
}
}
}
#[derive(Error, Debug, Display)]
#[allow(clippy::upper_case_acronyms)]
pub enum PKFilterError {
UnsupportedType(ValueType),
KeyError(#[from] ParseIntError),
}
pub fn text_pk_filter(key: String) -> Result<PrimaryKeyFilter, PKFilterError> {
Ok(PrimaryKeyFilter::text(key))
}
pub fn integer_pk_filter(key: &str) -> Result<PrimaryKeyFilter, PKFilterError> {
let value: i32 = key.parse().map_err(PKFilterError::KeyError)?;
Ok(PrimaryKeyFilter::integer(value))
}
pub fn bigint_pk_filter(key: &str) -> Result<PrimaryKeyFilter, PKFilterError> {
let value: i64 = key.parse().map_err(PKFilterError::KeyError)?;
Ok(PrimaryKeyFilter::bigint(value))
}
pub fn pk_filter<T: Into<String>>(
key: T,
field_type: ValueType,
) -> Result<PrimaryKeyFilter, PKFilterError> {
match field_type {
ValueType::Text => text_pk_filter(key.into()),
ValueType::Integer => integer_pk_filter(key.into().as_ref()),
ValueType::BigInt => bigint_pk_filter(key.into().as_ref()),
_ => Err(PKFilterError::UnsupportedType(field_type)),
}
}