use std::borrow::Cow;
use std::fmt::Display;
use std::ops::{Deref, DerefMut};
use ordered_varint::Variable;
use serde::{Deserialize, Serialize};
use super::ByteSource;
use crate::key::{Key, KeyEncoding, KeyKind};
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct VarInt<T>(pub T)
where
T: VariableInteger;
impl<T> Serialize for VarInt<T>
where
T: Serialize + VariableInteger,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.serialize(serializer)
}
}
impl<'de, T> Deserialize<'de> for VarInt<T>
where
T: Deserialize<'de> + VariableInteger,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
T::deserialize(deserializer).map(Self)
}
}
impl<T> Display for VarInt<T>
where
T: Display + VariableInteger,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl<T> From<T> for VarInt<T>
where
T: VariableInteger,
{
fn from(value: T) -> Self {
Self(value)
}
}
macro_rules! impl_varint_op {
($trait:ident, $method:ident) => {
impl<T> std::ops::$trait<T> for VarInt<T>
where
T: std::ops::$trait<T, Output = T> + VariableInteger,
{
type Output = Self;
fn $method(self, rhs: T) -> Self::Output {
Self(self.0.$method(rhs))
}
}
};
}
impl_varint_op!(Add, add);
impl_varint_op!(Sub, sub);
impl_varint_op!(Mul, mul);
impl_varint_op!(Div, div);
impl_varint_op!(Rem, rem);
impl_varint_op!(BitAnd, bitand);
impl_varint_op!(BitOr, bitor);
impl_varint_op!(BitXor, bitxor);
impl_varint_op!(Shl, shl);
impl_varint_op!(Shr, shr);
impl<T> std::ops::Not for VarInt<T>
where
T: std::ops::Not<Output = T> + VariableInteger,
{
type Output = Self;
fn not(self) -> Self::Output {
Self(self.0.not())
}
}
impl<T> Deref for VarInt<T>
where
T: VariableInteger,
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for VarInt<T>
where
T: VariableInteger,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<'k, T> Key<'k> for VarInt<T>
where
T: VariableInteger,
{
const CAN_OWN_BYTES: bool = false;
fn from_ord_bytes<'e>(bytes: ByteSource<'k, 'e>) -> Result<Self, Self::Error> {
T::decode_variable(bytes.as_ref()).map(Self)
}
}
impl<T> KeyEncoding for VarInt<T>
where
T: VariableInteger,
{
type Error = std::io::Error;
const LENGTH: Option<usize> = None;
fn describe<Visitor>(visitor: &mut Visitor)
where
Visitor: super::KeyVisitor,
{
visitor.visit_composite(
super::CompositeKind::Struct(Cow::Borrowed("bonsaidb::core::key::VarInt")),
1,
);
T::describe_contents(visitor);
}
fn as_ord_bytes(&self) -> Result<Cow<'_, [u8]>, Self::Error> {
let mut output = Vec::with_capacity(16);
self.0.encode_variable(&mut output)?;
Ok(Cow::Owned(output))
}
}
pub trait VariableInteger: Variable + Send + Sync + Clone + sealed::Sealed {}
mod sealed {
pub trait Sealed {
fn describe_contents<Visitor>(visitor: &mut Visitor)
where
Visitor: crate::key::KeyVisitor;
}
}
macro_rules! impl_variable_integer {
($type:ty, $kind:expr, $test:ident) => {
impl VariableInteger for $type {}
impl sealed::Sealed for $type {
fn describe_contents<Visitor>(visitor: &mut Visitor)
where
Visitor: super::KeyVisitor,
{
visitor.visit_type($kind);
}
}
impl From<VarInt<$type>> for $type {
fn from(value: VarInt<$type>) -> Self {
value.0
}
}
#[test]
fn $test() {
let i = VarInt::<$type>::from(0);
let r = 0;
let i = i + 2;
let r = r + 2;
assert_eq!(i, VarInt(r));
let i = i - 1;
let r = r - 1;
assert_eq!(i, VarInt(r));
let i = i * 6;
let r = r * 6;
assert_eq!(i, VarInt(r));
let i = i / 3;
let r = r / 3;
assert_eq!(i, VarInt(r));
let i = i % 2;
let r = r % 2;
assert_eq!(i, VarInt(r));
let i = !i;
let r = !r;
assert_eq!(i, VarInt(r));
let i = i >> 1;
let r = r >> 1;
assert_eq!(i, VarInt(r));
let i = i << 1;
let r = r << 1;
assert_eq!(i, VarInt(r));
let i = i & 0xF;
let r = r & 0xF;
assert_eq!(i, VarInt(r));
let i = i | 0x70;
let r = r | 0x70;
assert_eq!(i, VarInt(r));
let i = i ^ 0x18;
let r = r ^ 0x18;
assert_eq!(i, VarInt(r));
assert_eq!(Into::<$type>::into(i), r);
let encoded = i.as_ord_bytes().unwrap();
let decoded =
VarInt::<$type>::from_ord_bytes(crate::key::ByteSource::Borrowed(&encoded))
.unwrap();
assert_eq!(i, decoded);
let pot = transmog_pot::Pot::default();
let pot_encoded = transmog::Format::serialize(&pot, &i).unwrap();
let decoded =
transmog::OwnedDeserializer::deserialize_owned(&pot, &pot_encoded).unwrap();
assert_eq!(i, decoded);
}
};
}
impl_variable_integer!(u8, KeyKind::Unsigned, varint_u8_tests);
impl_variable_integer!(u16, KeyKind::Unsigned, varint_u16_tests);
impl_variable_integer!(u32, KeyKind::Unsigned, varint_u32_tests);
impl_variable_integer!(u64, KeyKind::Unsigned, varint_u64_tests);
impl_variable_integer!(u128, KeyKind::Unsigned, varint_u126_tests);
impl_variable_integer!(usize, KeyKind::Unsigned, varint_usize_tests);
impl_variable_integer!(i8, KeyKind::Signed, varint_i8_tests);
impl_variable_integer!(i16, KeyKind::Signed, varint_i16_tests);
impl_variable_integer!(i32, KeyKind::Signed, varint_i32_tests);
impl_variable_integer!(i64, KeyKind::Signed, varint_i64_tests);
impl_variable_integer!(i128, KeyKind::Signed, varint_i128_tests);
impl_variable_integer!(isize, KeyKind::Signed, varint_isize_tests);