use std::cmp::PartialEq;
use std::iter::FromIterator;
use serde_derive::{Deserialize, Serialize};
use crate::types::*;
#[derive(Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct Row {
pub(crate) inner: Vec<Raw>,
_buffer: Vec<u8>,
}
impl Row {
pub fn new(slice: &[u8]) -> Self {
let inner: Vec<Raw> = slice.iter().copied().collect::<Vec<u8>>().chunks(32).fold(
Vec::<Raw>::new(),
|mut vec, chunk| {
vec.push(chunk.into());
vec
},
);
Self {
inner,
..Default::default()
}
}
pub fn make_buffer(&mut self) {
self._buffer = self.inner.iter().fold(Vec::<u8>::new(), |mut vec, raw| {
vec.extend_from_slice(raw.as_ref());
vec
});
}
pub fn clean_buffer(&mut self) {
self._buffer = Vec::new();
}
pub fn to_utf8_string(&self) -> Result<String, std::string::FromUtf8Error> {
let buf = self.inner.iter().fold(Vec::<u8>::new(), |mut vec, raw| {
vec.extend_from_slice(raw.as_ref());
vec
});
String::from_utf8(buf)
}
pub fn into_raw_vec(self) -> Vec<Raw> {
self.inner
}
pub fn into_u8_vec(mut self) -> Vec<u8> {
self.make_buffer();
self._buffer
}
pub fn wipe_header(&mut self, header_size: usize) {
assert!(header_size <= 32);
self.inner[0].wipe_header(header_size);
}
}
impl ExactSizeIterator for Row {
fn len(&self) -> usize {
self.inner.len()
}
}
impl From<Vec<Raw>> for Row {
fn from(v: Vec<Raw>) -> Self {
Self {
inner: v,
..Default::default()
}
}
}
impl From<&[Raw]> for Row {
fn from(v: &[Raw]) -> Self {
Self {
inner: v.into(),
..Default::default()
}
}
}
impl Iterator for Row {
type Item = u8;
#[allow(clippy::never_loop)]
fn next(&mut self) -> Option<Self::Item> {
for raw in self.inner.iter() {
for b in raw.bytes.iter() {
return Some(*b);
}
}
None
}
}
impl Iterator for &Row {
type Item = u8;
#[allow(clippy::never_loop)]
fn next(&mut self) -> Option<Self::Item> {
for raw in self.inner.iter() {
for b in raw.bytes.iter() {
return Some(*b);
}
}
None
}
}
impl FromIterator<u8> for Row {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = u8>,
{
let row: Vec<Raw> = iter.into_iter().collect::<Vec<u8>>().chunks(32).fold(
Vec::<Raw>::new(),
|mut vec, chunk| {
vec.push(chunk.into());
vec
},
);
row.into()
}
}
impl From<&[u8]> for Row {
fn from(slice: &[u8]) -> Self {
Row::new(slice)
}
}
impl From<&str> for Row {
fn from(s: &str) -> Self {
Self::from(s.as_bytes())
}
}
impl From<String> for Row {
fn from(s: String) -> Self {
Self::from(s.as_bytes())
}
}
impl From<&String> for Row {
fn from(s: &String) -> Self {
Self::from(s.as_bytes())
}
}
impl From<&Raw> for Row {
fn from(v: &Raw) -> Self {
Self {
inner: vec![*v],
..Default::default()
}
}
}
impl From<Raw> for Row {
fn from(v: Raw) -> Self {
Self {
inner: vec![v],
..Default::default()
}
}
}
impl From<Vec<u8>> for Row {
fn from(v: Vec<u8>) -> Self {
let inner: Vec<Raw> = v.into_iter().collect::<Vec<u8>>().chunks(32).fold(
Vec::<Raw>::new(),
|mut vec, chunk| {
vec.push(chunk.into());
vec
},
);
Self {
inner,
..Default::default()
}
}
}
impl From<Box<[u8]>> for Row {
fn from(v: Box<[u8]>) -> Self {
Row::new(&v)
}
}
impl std::borrow::Borrow<[u8]> for Row {
fn borrow(&self) -> &[u8] {
if !self.inner.is_empty() && self._buffer.is_empty() {
panic!("make buffer before brrow")
}
self._buffer.as_ref()
}
}
impl std::borrow::Borrow<[u8]> for &Row {
fn borrow(&self) -> &[u8] {
if !self.inner.is_empty() && self._buffer.is_empty() {
panic!("make buffer before brrow")
}
self._buffer.as_ref()
}
}
macro_rules! from_array {
($($n:expr),*) => {
$(
impl From<&[Raw; $n]> for Row {
fn from(v: &[Raw; $n]) -> Self {
Self::from(v.to_vec())
}
}
impl From<Row> for [Raw; $n] {
fn from(r: Row) -> [Raw; $n]{
let mut buffer : [Raw; $n] = Default::default();
buffer.copy_from_slice(&r.inner[0..$n]);
buffer
}
}
)*
}
}
from_array!(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32
);