diff --git a/src/core/error/mod.rs b/src/core/error/mod.rs index 35bf9800..b84f1b46 100644 --- a/src/core/error/mod.rs +++ b/src/core/error/mod.rs @@ -35,6 +35,8 @@ pub enum Error { // third-party #[error(transparent)] + CapacityError(#[from] arrayvec::CapacityError), + #[error(transparent)] CargoToml(#[from] cargo_toml::Error), #[error(transparent)] Clap(#[from] clap::error::Error), diff --git a/src/database/de.rs b/src/database/de.rs index f8a038ef..d303eab2 100644 --- a/src/database/de.rs +++ b/src/database/de.rs @@ -1,3 +1,4 @@ +use arrayvec::ArrayVec; use conduit::{checked, debug::DebugInspect, err, utils::string, Error, Result}; use serde::{ de, @@ -52,7 +53,7 @@ impl<'de> Deserializer<'de> { let len = self.buf.len(); let parsed = &self.buf[0..pos]; let unparsed = &self.buf[pos..]; - let remain = checked!(len - pos)?; + let remain = self.remaining()?; let trailing_sep = remain == 1 && unparsed[0] == Self::SEP; (remain == 0 || trailing_sep) .then_some(()) @@ -139,6 +140,14 @@ impl<'de> Deserializer<'de> { self.pos = self.pos.saturating_add(n); debug_assert!(self.pos <= self.buf.len(), "pos out of range"); } + + /// Unconsumed input bytes. + #[inline] + fn remaining(&self) -> Result { + let pos = self.pos; + let len = self.buf.len(); + checked!(len - pos) + } } impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { @@ -240,8 +249,13 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } fn deserialize_i64>(self, visitor: V) -> Result { - let bytes: [u8; size_of::()] = self.buf[self.pos..].try_into()?; - self.inc_pos(size_of::()); + const BYTES: usize = size_of::(); + + let end = self.pos.saturating_add(BYTES); + let bytes: ArrayVec = self.buf[self.pos..end].try_into()?; + let bytes = bytes.into_inner().expect("array size matches i64"); + + self.inc_pos(BYTES); visitor.visit_i64(i64::from_be_bytes(bytes)) } @@ -258,8 +272,13 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } fn deserialize_u64>(self, visitor: V) -> Result { - let bytes: [u8; size_of::()] = self.buf[self.pos..].try_into()?; - self.inc_pos(size_of::()); + const BYTES: usize = size_of::(); + + let end = self.pos.saturating_add(BYTES); + let bytes: ArrayVec = self.buf[self.pos..end].try_into()?; + let bytes = bytes.into_inner().expect("array size matches u64"); + + self.inc_pos(BYTES); visitor.visit_u64(u64::from_be_bytes(bytes)) }