mod from_bytes;
mod into_bytes;
use serde::{Deserialize, Serialize};
use std::iter::FromIterator;
use std::ops::Index;
use std::slice::SliceIndex;
use crate::ron::{FromRon, ToRon};
#[derive(Default, Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct Bytes(Vec<u8>);
impl<Idx> Index<Idx> for Bytes
where
Idx: SliceIndex<[u8]>,
{
type Output = Idx::Output;
fn index(&self, index: Idx) -> &Self::Output {
&self.as_slice()[index]
}
}
impl IntoIterator for Bytes {
type Item = u8;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl FromIterator<u8> for Bytes {
fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
let mut bytes = Bytes::empty();
for byte in iter {
bytes.push(byte)
}
bytes
}
}
impl std::fmt::Display for Bytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let string = String::from_utf8_lossy(&self.0).to_string();
write!(f, "{}", string)
}
}
impl FromRon<'_> for Bytes {}
impl ToRon for Bytes {}
impl Bytes {
pub fn new(content: Vec<u8>) -> Self {
Bytes(content)
}
pub fn empty() -> Self {
Bytes(Vec::new())
}
pub fn push(&mut self, value: u8) {
self.0.push(value)
}
pub fn as_slice(&self) -> &[u8] {
&self.0
}
pub fn vec(&self) -> Vec<u8> {
self.0.clone()
}
pub fn vec_ref(&self) -> &Vec<u8> {
&self.0
}
pub fn vec_mut(&mut self) -> &mut Vec<u8> {
&mut self.0
}
pub fn into_vec(self) -> Vec<u8> {
self.0
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn append(&mut self, other: &mut Bytes) {
self.0.append(other.vec_mut())
}
pub fn get(&self, index: usize) -> Option<u8> {
let value = self.as_slice().get(index);
value.copied()
}
pub fn find_pattern(&self, pattern: &Bytes) -> Option<Vec<usize>> {
let pattern_slice = pattern.as_slice();
let mut indexes: Option<Vec<usize>> = None;
let mut i = 0;
while i < self.len() {
if self.get(i + pattern_slice.len()).is_none() {
break;
}
let pattern_to_check = &self[i..i + pattern_slice.len()];
if pattern_to_check == pattern_slice {
match indexes {
Some(ref mut vec) => {
vec.push(i);
}
None => {
indexes = Some(vec![i]);
}
}
i += 4;
} else {
i += 1;
}
}
indexes
}
pub fn split_at_pat(self, pattern: &Bytes) -> Vec<Bytes> {
let mut split = Vec::new();
let indexes = self.find_pattern(pattern);
if indexes.is_none() {
split.push(self);
return split;
}
let indexes = indexes.unwrap();
let mut part = Bytes::empty();
let mut i = 0;
while i < self.len() {
if indexes.contains(&i) {
split.push(part);
part = Bytes::empty();
i += pattern.len();
}
part.push(self[i]);
i += 1;
}
if !part.is_empty() {
split.push(part);
}
split
}
}
#[test]
fn find_pattern_test() {
let bytes = Bytes::from([1, 2, 3, 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, 0, 8, 9, 10]);
let indexes = bytes.find_pattern(&Bytes::from([0, 0, 0, 0]));
println!("Result: {indexes:?}");
assert_eq!(indexes, Some(vec![3, 10]));
}
#[test]
fn split_at_pat_test() {
let bytes = Bytes::from([1, 2, 3, 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, 0, 8, 9, 10]);
let split = bytes.split_at_pat(&Bytes::from([0, 0, 0, 0]));
println!("{:?}", split);
assert_eq!(
split,
vec![
Bytes::from([1, 2, 3]),
Bytes::from([5, 6, 7]),
Bytes::from([8, 9, 10])
]
)
}