From 454db37ace74a68e3a6a48bacc4dce8ba5e5234e Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Wed, 11 Sep 2024 13:42:50 -0500 Subject: [PATCH 1/2] Add encoding::LengthString --- src/encoding.rs | 156 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/src/encoding.rs b/src/encoding.rs index b374996f..bd7f22ee 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -185,6 +185,162 @@ where } } +#[derive( + Deref, + DerefMut, + Into, + Default, + Clone, + Debug, + FieldQuery, + PartialEq, + Hash, + Eq, + Describe, + Serialize, + Deserialize, +)] +#[serde(transparent)] +pub struct LengthString

+where + P: Encode + Decode + TryInto + Terminated + Clone + 'static, +{ + #[serde(skip)] + len: P, + + #[deref] + #[deref_mut] + #[into] + inner: String, +} + +impl

Migrate for LengthString

where + P: Encode + Decode + TryInto + Terminated + Clone + 'static +{ +} + +impl

LengthString

+where + P: Encode + Decode + TryInto + Terminated + Clone, +{ + pub fn new(len: P, inner: String) -> Self { + LengthString { len, inner } + } +} + +impl

Decode for LengthString

+where + P: Encode + Decode + Terminated + TryInto + Clone, +{ + fn decode(mut input: R) -> Result { + let len = P::decode(&mut input)?; + + let len_usize = len + .clone() + .try_into() + .map_err(|_| Error::UnexpectedByte(80))?; + + let mut inner = String::with_capacity(len_usize); + for _ in 0..len_usize { + let value = u8::decode(&mut input)?; + inner.push(value as char); + } + + Ok(LengthString { len, inner }) + } +} + +impl

Encode for LengthString

+where + P: Encode + Decode + TryInto + Terminated + Clone, +{ + fn encode_into(&self, mut out: &mut W) -> Result<()> { + self.len.encode_into(&mut out)?; + for c in self.inner.chars() { + (c as u8).encode_into(&mut out)?; + } + + Ok(()) + } + + fn encoding_length(&self) -> Result { + let mut len = self.len.encoding_length()?; + for c in self.inner.chars() { + len += (c as u8).encoding_length()?; + } + + Ok(len) + } +} + +impl

Terminated for LengthString

where P: Encode + Decode + TryInto + Terminated + Clone +{} + +impl

State for LengthString

+where + P: Encode + Decode + TryInto + Terminated + Clone + 'static, +{ + fn attach(&mut self, _store: Store) -> crate::Result<()> { + Ok(()) + } + + fn flush(self, out: &mut W) -> crate::Result<()> { + self.len.encode_into(out)?; + // TODO: non-utf8 support? + self.inner.as_bytes().encode_into(out)?; + + Ok(()) + } + + fn load(_store: Store, mut bytes: &mut &[u8]) -> crate::Result { + let len = P::decode(&mut bytes)?; + let len_usize = len + .clone() + .try_into() + .map_err(|_| Error::UnexpectedByte(80))?; + + let mut inner = String::with_capacity(len_usize); + for _ in 0..len_usize { + let value = u8::decode(&mut bytes)?; + inner.push(value as char); + } + + Ok(LengthString { len, inner }) + } +} + +impl

TryFrom<&str> for LengthString

+where + P: State + Encode + Decode + TryInto + TryFrom + Terminated + Clone, +{ + type Error = crate::Error; + + fn try_from(value: &str) -> crate::Result { + value.to_string().try_into() + } +} + +// impl

Describe for LengthString

+// where +// P: State + Encode + Decode + TryInto + Terminated + Clone + 'static, +// { +// fn describe() -> crate::describe::Descriptor { +// crate::describe::Builder::new::().build() +// } +// } + +impl

TryFrom for LengthString

+where + P: State + Encode + Decode + TryInto + TryFrom + Terminated + Clone, +{ + type Error = crate::Error; + + fn try_from(inner: String) -> crate::Result { + let len = inner.len().try_into().map_err(|_| crate::Error::Overflow)?; + Ok(Self { len, inner }) + } +} + #[derive(Clone, Debug)] pub struct Adapter(pub T); From d3b71d98d367a615b3ed59aa8a18060daab920bc Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Wed, 11 Sep 2024 13:48:38 -0500 Subject: [PATCH 2/2] Format --- src/encoding.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/encoding.rs b/src/encoding.rs index bd7f22ee..71ba5905 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -322,8 +322,8 @@ where // impl

Describe for LengthString

// where -// P: State + Encode + Decode + TryInto + Terminated + Clone + 'static, -// { +// P: State + Encode + Decode + TryInto + Terminated + Clone + +// 'static, { // fn describe() -> crate::describe::Descriptor { // crate::describe::Builder::new::().build() // }