wtx 0.43.0

A collection of different transport implementations and related tools focused primarily on web technologies.
Documentation
use crate::{
  codec::Decode,
  collection::Vector,
  database::client::mysql::{
    MysqlError,
    protocol::{Protocol, decode_wrapper_protocol::DecodeWrapperProtocol, lenenc::Lenenc},
  },
  misc::Usize,
};
use core::ops::Range;

type Params<'any> = (usize, &'any mut Vector<(bool, Range<usize>)>);

#[derive(Debug)]
pub(crate) struct TextRowRes<'de>(pub(crate) &'de [u8]);

impl<'de, E> Decode<'de, Protocol<Params<'_>, E>> for TextRowRes<'de>
where
  E: From<crate::Error>,
{
  #[inline]
  fn decode(dw: &mut DecodeWrapperProtocol<'de, '_, Params<'_>>) -> Result<Self, E> {
    let columns = dw.other.0;
    dw.other.1.reserve(columns)?;
    let initial = *dw.bytes;
    let mut idx = 0;
    for _ in 0..columns {
      let [first, rest @ ..] = dw.bytes else {
        return Err(E::from(MysqlError::InvalidTextRowBytes.into()));
      };
      if *first == 251 {
        dw.other.1.push((true, idx..idx))?;
        *dw.bytes = rest;
        idx = idx.wrapping_add(1);
      } else {
        let len = {
          let begin = dw.bytes.len();
          let len = Usize::from(Lenenc::decode(dw)?.0).into_usize();
          let consumed_bytes = begin.wrapping_sub(dw.bytes.len());
          idx = idx.wrapping_add(consumed_bytes);
          len
        };
        let begin = idx;
        idx = idx.wrapping_add(len);
        *dw.bytes = dw.bytes.get(len..).unwrap_or_default();
        dw.other.1.push((false, begin..idx))?;
      }
    }
    Ok(Self(initial))
  }
}

#[cfg(test)]
mod tests {
  use crate::{
    codec::Decode,
    collection::Vector,
    database::client::mysql::protocol::{
      decode_wrapper_protocol::DecodeWrapperProtocol, text_row_res::TextRowRes,
    },
  };

  #[test]
  fn has_correct_indices() {
    let mut vector = Vector::new();
    let bytes = &mut &[4, b't', b'e', b's', b't'][..];
    let mut dw = DecodeWrapperProtocol { bytes, other: (1, &mut vector) };
    let rslt: crate::Result<_> = TextRowRes::decode(&mut dw);
    let _text_row_res = rslt.unwrap();
    assert_eq!(vector.as_ref(), &[(false, 1..5)]);
  }
}