Skip to content
This repository was archived by the owner on Apr 2, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions src/bstr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use super::*;
use core::bstr::ByteStr;
Comment on lines +1 to +2

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding module-level documentation to explain the purpose of this module and when users should use ByteStr as an input type. Additionally, the Input trait documentation in src/input.rs (around lines 25-29) should be updated to include ByteStr in the list of common input types and their implemented traits, similar to how &str and &[T] are documented.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, listing it is superfluous and the impl will appear in the docs anyway


impl<'src> Input<'src> for &'src ByteStr {
type Cursor = usize;
type Span = SimpleSpan<usize>;

type Token = u8;
type MaybeToken = u8;

type Cache = Self;

#[inline]
fn begin(self) -> (Self::Cursor, Self::Cache) {
(0, self)
}

#[inline]
fn cursor_location(cursor: &Self::Cursor) -> usize {
*cursor
}

#[inline(always)]
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::MaybeToken> {
if let Some(tok) = this.get(*cursor) {
*cursor += 1;
Some(*tok)
} else {
None
}
}

#[inline(always)]
unsafe fn span(_this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span {
(*range.start..*range.end).into()
}
}

impl<'src> ExactSizeInput<'src> for &'src ByteStr {
#[inline(always)]
unsafe fn span_from(this: &mut Self::Cache, range: RangeFrom<&Self::Cursor>) -> Self::Span {
(*range.start..this.len()).into()
}
}

impl Sealed for &ByteStr {}
impl<'src> StrInput<'src> for &'src ByteStr {
#[doc(hidden)]
fn stringify(slice: Self::Slice) -> String {
slice
.iter()
// .map(|e| core::ascii::Char::from_u8(e).unwrap_or(AsciiChar::Substitute).to_char())
.map(|e| char::from(*e))
.collect()
}
}

impl<'src> SliceInput<'src> for &'src ByteStr {
type Slice = &'src ByteStr;

#[inline(always)]
fn full_slice(this: &mut Self::Cache) -> Self::Slice {
*this
}

#[inline(always)]
unsafe fn slice(this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Slice {
&this[*range.start..*range.end]
}

#[inline(always)]
unsafe fn slice_from(this: &mut Self::Cache, from: RangeFrom<&Self::Cursor>) -> Self::Slice {
&this[*from.start..]
}
}

impl<'src> ValueInput<'src> for &'src ByteStr {
#[inline(always)]
unsafe fn next(this: &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token> {
Self::next_maybe(this, cursor)
}
}
11 changes: 10 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
#![cfg_attr(docsrs, feature(doc_cfg), deny(rustdoc::all))]
#![cfg_attr(
feature = "nightly",
feature(never_type, fn_traits, tuple_trait, unboxed_closures, specialization)
feature(
never_type,
fn_traits,
tuple_trait,
unboxed_closures,
specialization,
bstr
)
)]
#![cfg_attr(feature = "nightly", allow(incomplete_features))]
#![doc = include_str!("../README.md")]
Expand Down Expand Up @@ -33,6 +40,8 @@ macro_rules! go_extra {
}

mod blanket;
#[cfg(feature = "nightly")]
mod bstr;
#[cfg(feature = "unstable")]
pub mod cache;
pub mod combinator;
Expand Down