#![cfg(all(feature = "parse", not(feature = "format")))]
use crate::iterator::BytesIter;
use core::{mem, ptr};
pub trait AsBytes<'a> {
fn bytes<const __: u128>(&'a self) -> Bytes<'a, __>;
}
impl<'a> AsBytes<'a> for [u8] {
#[inline]
fn bytes<const __: u128>(&'a self) -> Bytes<'a, __> {
Bytes::new(self)
}
}
#[derive(Clone)]
pub struct Bytes<'a, const __: u128> {
slc: &'a [u8],
index: usize,
}
impl<'a, const __: u128> Bytes<'a, __> {
pub const IS_CONTIGUOUS: bool = true;
#[inline]
pub const fn new(slc: &'a [u8]) -> Self {
Self {
slc,
index: 0,
}
}
#[inline]
pub fn as_ptr(&self) -> *const u8 {
self.as_slice().as_ptr()
}
#[inline]
pub fn as_slice(&self) -> &'a [u8] {
debug_assert!(self.index <= self.length());
unsafe { self.slc.get_unchecked(self.index..) }
}
#[inline]
pub fn length(&self) -> usize {
self.slc.len()
}
#[inline]
pub fn cursor(&self) -> usize {
self.index
}
#[inline]
pub unsafe fn set_cursor(&mut self, index: usize) {
debug_assert!(index <= self.length());
self.index = index
}
#[inline]
pub fn current_count(&self) -> usize {
self.index
}
#[inline]
pub fn is_done(&self) -> bool {
self.index >= self.slc.len()
}
#[inline]
#[allow(clippy::assertions_on_constants)]
pub unsafe fn read_unchecked<V>(&self) -> V {
debug_assert!(Self::IS_CONTIGUOUS);
debug_assert!(self.as_slice().len() >= mem::size_of::<V>());
let slc = self.as_slice();
unsafe { ptr::read_unaligned::<V>(slc.as_ptr() as *const _) }
}
#[inline]
pub fn read<V>(&self) -> Option<V> {
if Self::IS_CONTIGUOUS && self.as_slice().len() >= mem::size_of::<V>() {
unsafe { Some(self.read_unchecked()) }
} else {
None
}
}
#[inline]
pub fn first_is(&mut self, value: u8) -> bool {
if let Some(&c) = self.slc.get(self.index) {
c == value
} else {
false
}
}
#[inline]
pub fn case_insensitive_first_is(&mut self, value: u8) -> bool {
if let Some(&c) = self.slc.get(self.index) {
c.to_ascii_lowercase() == value.to_ascii_lowercase()
} else {
false
}
}
#[inline]
pub fn integer_iter<'b>(&'b mut self) -> BytesIterator<'a, 'b, __> {
BytesIterator {
byte: self,
}
}
#[inline]
pub fn fraction_iter<'b>(&'b mut self) -> BytesIterator<'a, 'b, __> {
BytesIterator {
byte: self,
}
}
#[inline]
pub fn exponent_iter<'b>(&'b mut self) -> BytesIterator<'a, 'b, __> {
BytesIterator {
byte: self,
}
}
#[inline]
pub fn special_iter<'b>(&'b mut self) -> BytesIterator<'a, 'b, __> {
BytesIterator {
byte: self,
}
}
#[inline]
#[allow(clippy::assertions_on_constants)]
pub unsafe fn step_by_unchecked(&mut self, count: usize) {
debug_assert!(Self::IS_CONTIGUOUS);
debug_assert!(self.as_slice().len() >= count);
self.index += count;
}
#[inline]
#[allow(clippy::assertions_on_constants)]
pub unsafe fn step_unchecked(&mut self) {
debug_assert!(Self::IS_CONTIGUOUS);
debug_assert!(!self.as_slice().is_empty());
self.index += 1;
}
}
pub struct BytesIterator<'a: 'b, 'b, const __: u128> {
byte: &'b mut Bytes<'a, __>,
}
impl<'a: 'b, 'b, const __: u128> BytesIter<'a> for BytesIterator<'a, 'b, __> {
const IS_CONTIGUOUS: bool = Bytes::<'a, __>::IS_CONTIGUOUS;
#[inline]
fn as_ptr(&self) -> *const u8 {
self.byte.as_ptr()
}
#[inline]
fn as_slice(&self) -> &'a [u8] {
self.byte.as_slice()
}
#[inline]
fn length(&self) -> usize {
self.byte.length()
}
#[inline]
fn cursor(&self) -> usize {
self.byte.cursor()
}
#[inline]
unsafe fn set_cursor(&mut self, index: usize) {
debug_assert!(index <= self.length());
unsafe { self.byte.set_cursor(index) };
}
#[inline]
fn current_count(&self) -> usize {
self.byte.current_count()
}
#[inline]
fn is_consumed(&mut self) -> bool {
Self::is_done(self)
}
#[inline]
fn is_done(&self) -> bool {
self.byte.is_done()
}
#[inline]
unsafe fn peek_unchecked(&mut self) -> <Self as Iterator>::Item {
unsafe { self.byte.slc.get_unchecked(self.byte.index) }
}
#[inline]
fn peek(&mut self) -> Option<<Self as Iterator>::Item> {
if self.byte.index < self.byte.slc.len() {
Some(unsafe { self.peek_unchecked() })
} else {
None
}
}
#[inline]
unsafe fn read_unchecked<V>(&self) -> V {
debug_assert!(self.as_slice().len() >= mem::size_of::<V>());
unsafe { self.byte.read_unchecked() }
}
#[inline]
fn read<V>(&self) -> Option<V> {
self.byte.read()
}
#[inline]
unsafe fn step_by_unchecked(&mut self, count: usize) {
debug_assert!(self.as_slice().len() >= count);
unsafe { self.byte.step_by_unchecked(count) }
}
#[inline]
unsafe fn step_unchecked(&mut self) {
debug_assert!(!self.as_slice().is_empty());
unsafe { self.byte.step_unchecked() }
}
}
impl<'a: 'b, 'b, const __: u128> Iterator for BytesIterator<'a, 'b, __> {
type Item = &'a u8;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let value = self.byte.slc.get(self.byte.index)?;
self.byte.index += 1;
Some(value)
}
}
impl<'a: 'b, 'b, const __: u128> ExactSizeIterator for BytesIterator<'a, 'b, __> {
#[inline]
fn len(&self) -> usize {
self.length() - self.cursor()
}
}