diff --git a/Cargo.toml b/Cargo.toml index ef0e3eb7c..690f25cee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ kv_unstable_serde = ["kv_unstable_std", "value-bag/serde", "serde"] serde = { version = "1.0", optional = true, default-features = false } sval = { version = "2.1", optional = true, default-features = false } sval_ref = { version = "2.1", optional = true, default-features = false } -value-bag = { version = "1.4", optional = true, default-features = false } +value-bag = { version = "1.4", optional = true, default-features = false, features = ["inline-i128"] } [dev-dependencies] serde = { version = "1.0", features = ["derive"] } diff --git a/src/kv/value.rs b/src/kv/value.rs index c8cdf6dbb..f5f4fc057 100644 --- a/src/kv/value.rs +++ b/src/kv/value.rs @@ -260,62 +260,12 @@ impl ToValue for str { } } -impl ToValue for u128 { - fn to_value(&self) -> Value { - Value::from(self) - } -} - -impl ToValue for i128 { - fn to_value(&self) -> Value { - Value::from(self) - } -} - -impl ToValue for std::num::NonZeroU128 { - fn to_value(&self) -> Value { - Value::from(self) - } -} - -impl ToValue for std::num::NonZeroI128 { - fn to_value(&self) -> Value { - Value::from(self) - } -} - impl<'v> From<&'v str> for Value<'v> { fn from(value: &'v str) -> Self { Value::from_inner(value) } } -impl<'v> From<&'v u128> for Value<'v> { - fn from(value: &'v u128) -> Self { - Value::from_inner(value) - } -} - -impl<'v> From<&'v i128> for Value<'v> { - fn from(value: &'v i128) -> Self { - Value::from_inner(value) - } -} - -impl<'v> From<&'v std::num::NonZeroU128> for Value<'v> { - fn from(v: &'v std::num::NonZeroU128) -> Value<'v> { - // SAFETY: `NonZeroU128` and `u128` have the same ABI - Value::from_inner(unsafe { &*(v as *const std::num::NonZeroU128 as *const u128) }) - } -} - -impl<'v> From<&'v std::num::NonZeroI128> for Value<'v> { - fn from(v: &'v std::num::NonZeroI128) -> Value<'v> { - // SAFETY: `NonZeroI128` and `i128` have the same ABI - Value::from_inner(unsafe { &*(v as *const std::num::NonZeroI128 as *const i128) }) - } -} - impl ToValue for () { fn to_value(&self) -> Value { Value::from_inner(()) @@ -383,12 +333,12 @@ macro_rules! impl_value_to_primitive { } } -impl_to_value_primitive![usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, f32, f64, char, bool,]; +impl_to_value_primitive![usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64, char, bool,]; #[rustfmt::skip] impl_to_value_nonzero_primitive![ - NonZeroUsize, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, - NonZeroIsize, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, + NonZeroUsize, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, + NonZeroIsize, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, ]; impl_value_to_primitive![ @@ -503,6 +453,11 @@ pub trait Visitor<'v> { /// or serialized using its `sval::Value` or `serde::Serialize` implementation. fn visit_any(&mut self, value: Value) -> Result<(), Error>; + /// Visit an empty value. + fn visit_null(&mut self) -> Result<(), Error> { + self.visit_any(Value::null()) + } + /// Visit an unsigned integer. fn visit_u64(&mut self, value: u64) -> Result<(), Error> { self.visit_any(value.into()) @@ -515,12 +470,12 @@ pub trait Visitor<'v> { /// Visit a big unsigned integer. fn visit_u128(&mut self, value: u128) -> Result<(), Error> { - self.visit_any((&value).into()) + self.visit_any((value).into()) } /// Visit a big signed integer. fn visit_i128(&mut self, value: i128) -> Result<(), Error> { - self.visit_any((&value).into()) + self.visit_any((value).into()) } /// Visit a floating point. @@ -573,6 +528,10 @@ where (**self).visit_any(value) } + fn visit_null(&mut self) -> Result<(), Error> { + (**self).visit_null() + } + fn visit_u64(&mut self, value: u64) -> Result<(), Error> { (**self).visit_u64(value) } @@ -739,188 +698,287 @@ pub(in crate::kv) mod inner { #[derive(Clone)] pub enum Inner<'v> { + None, + Bool(bool), Str(&'v str), + Char(char), + I64(i64), + U64(u64), + F64(f64), + I128(i128), + U128(u128), + Debug(&'v dyn fmt::Debug), + Display(&'v dyn fmt::Display), } impl<'v> From<()> for Inner<'v> { fn from(v: ()) -> Self { - todo!() + Inner::None } } impl<'v> From for Inner<'v> { fn from(v: bool) -> Self { - todo!() + Inner::Bool(v) } } impl<'v> From for Inner<'v> { fn from(v: char) -> Self { - todo!() + Inner::Char(v) } } impl<'v> From for Inner<'v> { fn from(v: f32) -> Self { - todo!() + Inner::F64(v as f64) } } impl<'v> From for Inner<'v> { fn from(v: f64) -> Self { - todo!() + Inner::F64(v) } } impl<'v> From for Inner<'v> { fn from(v: i8) -> Self { - todo!() + Inner::I64(v as i64) } } impl<'v> From for Inner<'v> { fn from(v: i16) -> Self { - todo!() + Inner::I64(v as i64) } } impl<'v> From for Inner<'v> { fn from(v: i32) -> Self { - todo!() + Inner::I64(v as i64) } } impl<'v> From for Inner<'v> { fn from(v: i64) -> Self { - todo!() + Inner::I64(v as i64) } } impl<'v> From for Inner<'v> { fn from(v: isize) -> Self { - todo!() + Inner::I64(v as i64) } } impl<'v> From for Inner<'v> { fn from(v: u8) -> Self { - todo!() + Inner::U64(v as u64) } } impl<'v> From for Inner<'v> { fn from(v: u16) -> Self { - todo!() + Inner::U64(v as u64) } } impl<'v> From for Inner<'v> { fn from(v: u32) -> Self { - todo!() + Inner::U64(v as u64) } } impl<'v> From for Inner<'v> { fn from(v: u64) -> Self { - todo!() + Inner::U64(v as u64) } } impl<'v> From for Inner<'v> { fn from(v: usize) -> Self { - todo!() + Inner::U64(v as u64) } } - impl<'v> From<&'v i128> for Inner<'v> { - fn from(v: &'v i128) -> Self { - todo!() + impl<'v> From for Inner<'v> { + fn from(v: i128) -> Self { + Inner::I128(v) } } - impl<'v> From<&'v u128> for Inner<'v> { - fn from(v: &'v u128) -> Self { - todo!() + impl<'v> From for Inner<'v> { + fn from(v: u128) -> Self { + Inner::U128(v) } } impl<'v> From<&'v str> for Inner<'v> { fn from(v: &'v str) -> Self { - todo!() + Inner::Str(v) } } impl<'v> fmt::Debug for Inner<'v> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - todo!() + match self { + Inner::None => fmt::Debug::fmt(&None::<()>, f), + Inner::Bool(v) => fmt::Debug::fmt(v, f), + Inner::Str(v) => fmt::Debug::fmt(v, f), + Inner::Char(v) => fmt::Debug::fmt(v, f), + Inner::I64(v) => fmt::Debug::fmt(v, f), + Inner::U64(v) => fmt::Debug::fmt(v, f), + Inner::F64(v) => fmt::Debug::fmt(v, f), + Inner::I128(v) => fmt::Debug::fmt(v, f), + Inner::U128(v) => fmt::Debug::fmt(v, f), + Inner::Debug(v) => fmt::Debug::fmt(v, f), + Inner::Display(v) => fmt::Display::fmt(v, f), + } } } impl<'v> fmt::Display for Inner<'v> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - todo!() + match self { + Inner::None => fmt::Debug::fmt(&None::<()>, f), + Inner::Bool(v) => fmt::Display::fmt(v, f), + Inner::Str(v) => fmt::Display::fmt(v, f), + Inner::Char(v) => fmt::Display::fmt(v, f), + Inner::I64(v) => fmt::Display::fmt(v, f), + Inner::U64(v) => fmt::Display::fmt(v, f), + Inner::F64(v) => fmt::Display::fmt(v, f), + Inner::I128(v) => fmt::Display::fmt(v, f), + Inner::U128(v) => fmt::Display::fmt(v, f), + Inner::Debug(v) => fmt::Debug::fmt(v, f), + Inner::Display(v) => fmt::Display::fmt(v, f), + } } } impl<'v> Inner<'v> { pub fn from_debug(value: &'v T) -> Self { - todo!() + Inner::Debug(value) } pub fn from_display(value: &'v T) -> Self { - todo!() + Inner::Display(value) } pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self { - todo!() + Inner::Debug(value) } pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self { - todo!() + Inner::Display(value) } pub fn empty() -> Self { - todo!() + Inner::None } pub fn to_bool(&self) -> Option { - todo!() + match self { + Inner::Bool(v) => Some(*v), + _ => None, + } } pub fn to_char(&self) -> Option { - todo!() + match self { + Inner::Char(v) => Some(*v), + _ => None, + } } pub fn to_f64(&self) -> Option { - todo!() + match self { + Inner::F64(v) => Some(*v), + Inner::I64(v) => { + let v: i32 = (*v).try_into().ok()?; + v.try_into().ok() + }, + Inner::U64(v) => { + let v: u32 = (*v).try_into().ok()?; + v.try_into().ok() + }, + Inner::I128(v) => { + let v: i32 = (*v).try_into().ok()?; + v.try_into().ok() + }, + Inner::U128(v) => { + let v: u32 = (*v).try_into().ok()?; + v.try_into().ok() + }, + _ => None, + } } pub fn to_i64(&self) -> Option { - todo!() + match self { + Inner::I64(v) => Some(*v), + Inner::U64(v) => (*v).try_into().ok(), + Inner::I128(v) => (*v).try_into().ok(), + Inner::U128(v) => (*v).try_into().ok(), + _ => None, + } } pub fn to_u64(&self) -> Option { - todo!() + match self { + Inner::U64(v) => Some(*v), + Inner::I64(v) => (*v).try_into().ok(), + Inner::I128(v) => (*v).try_into().ok(), + Inner::U128(v) => (*v).try_into().ok(), + _ => None, + } } pub fn to_u128(&self) -> Option { - todo!() + match self { + Inner::U128(v) => Some(*v), + Inner::I64(v) => (*v).try_into().ok(), + Inner::U64(v) => (*v).try_into().ok(), + Inner::I128(v) => (*v).try_into().ok(), + _ => None, + } } pub fn to_i128(&self) -> Option { - todo!() + match self { + Inner::I128(v) => Some(*v), + Inner::I64(v) => (*v).try_into().ok(), + Inner::U64(v) => (*v).try_into().ok(), + Inner::U128(v) => (*v).try_into().ok(), + _ => None, + } } pub fn to_borrowed_str(&self) -> Option<&'v str> { - todo!() + match self { + Inner::Str(v) => Some(v), + _ => None, + } } #[cfg(test)] pub fn to_test_token(&self) -> Token { - todo!() + match self { + Inner::None => Token::None, + Inner::Bool(v) => Token::Bool(*v), + Inner::Str(v) => Token::Str(*v), + Inner::Char(v) => Token::Char(*v), + Inner::I64(v) => Token::I64(*v), + Inner::U64(v) => Token::U64(*v), + Inner::F64(v) => Token::F64(*v), + Inner::I128(v) => unimplemented!(), + Inner::U128(v) => unimplemented!(), + Inner::Debug(v) => unimplemented!(), + Inner::Display(v) => unimplemented!(), + } } } + #[cfg(test)] #[derive(Debug, PartialEq)] pub enum Token<'v> { None,