Skip to content

Commit

Permalink
Renamed TokenMaybe to MaybeToken, tightened up some API corners
Browse files Browse the repository at this point in the history
  • Loading branch information
zesterer committed Oct 21, 2024
1 parent d532d92 commit 9d31654
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 65 deletions.
76 changes: 18 additions & 58 deletions src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,6 @@ use super::*;
#[cfg(feature = "std")]
use std::io::{BufReader, Read, Seek};

mod sealed {
pub trait Sealed<T> {}
}
#[doc(hidden)]
pub trait MaybeOwned<'src, T: 'src>:
sealed::Sealed<T> + Borrow<T> + Into<MaybeRef<'src, T>>
{
type Proj<U: 'src>: MaybeOwned<'src, U>;
#[doc(hidden)]
fn choose<R: 'src>(
self,
f: impl FnOnce(&'src T) -> &'src R,
g: impl FnOnce(T) -> R,
) -> Self::Proj<R>;
}

impl<T> sealed::Sealed<T> for &T {}
impl<'src, T> MaybeOwned<'src, T> for &'src T {
type Proj<U: 'src> = &'src U;
fn choose<R: 'src>(
self,
f: impl FnOnce(&'src T) -> &'src R,
_g: impl FnOnce(T) -> R,
) -> Self::Proj<R> {
f(self)
}
}

impl<T> sealed::Sealed<T> for T {}
impl<'src, T: 'src> MaybeOwned<'src, T> for T {
type Proj<U: 'src> = U;
fn choose<R: 'src>(
self,
_f: impl FnOnce(&'src T) -> &'src R,
g: impl FnOnce(T) -> R,
) -> Self::Proj<R> {
g(self)
}
}

/// A trait for types that represents a stream of input tokens. Unlike [`Iterator`], this type
/// supports backtracking and a few other features required by the crate.
///
Expand All @@ -73,7 +33,7 @@ pub trait Input<'src>: 'src {
type Token: 'src;

/// The token type returned by [`Input::next_maybe`], allows abstracting over by-value and by-reference inputs.
type TokenMaybe: MaybeOwned<'src, Self::Token>; // Must be `&'src Self::Token` or `Self::Token`
type MaybeToken: IntoMaybe<'src, Self::Token>; // Must be `&'src Self::Token` or `Self::Token`

/// The type used to keep track of the current location in the stream.
///
Expand Down Expand Up @@ -101,7 +61,7 @@ pub trait Input<'src>: 'src {
unsafe fn next_maybe(
cache: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe>;
) -> Option<Self::MaybeToken>;

/// Create a span going from the start cursor to the end cursor (exclusive).
///
Expand Down Expand Up @@ -247,7 +207,7 @@ impl<'src> Input<'src> for &'src str {
type Span = SimpleSpan<usize>;

type Token = char;
type TokenMaybe = char;
type MaybeToken = char;

type Cache = Self;

Expand All @@ -265,7 +225,7 @@ impl<'src> Input<'src> for &'src str {
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe> {
) -> Option<Self::MaybeToken> {
if *cursor < this.len() {
// SAFETY: `cursor < self.len()` above guarantees cursor is in-bounds
// We only ever return cursors that are at a character boundary
Expand Down Expand Up @@ -328,7 +288,7 @@ impl<'src, T> Input<'src> for &'src [T] {
type Span = SimpleSpan<usize>;

type Token = T;
type TokenMaybe = &'src T;
type MaybeToken = &'src T;

type Cache = Self;

Expand All @@ -346,7 +306,7 @@ impl<'src, T> Input<'src> for &'src [T] {
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe> {
) -> Option<Self::MaybeToken> {
if let Some(tok) = this.get(*cursor) {
*cursor += 1;
Some(tok)
Expand Down Expand Up @@ -412,7 +372,7 @@ impl<'src, T: 'src, const N: usize> Input<'src> for &'src [T; N] {
type Span = SimpleSpan<usize>;

type Token = T;
type TokenMaybe = &'src T;
type MaybeToken = &'src T;

type Cache = Self;

Expand All @@ -430,7 +390,7 @@ impl<'src, T: 'src, const N: usize> Input<'src> for &'src [T; N] {
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe> {
) -> Option<Self::MaybeToken> {
if let Some(tok) = this.get(*cursor) {
*cursor += 1;
Some(tok)
Expand Down Expand Up @@ -509,7 +469,7 @@ where
type Span = S;

type Token = T;
type TokenMaybe = <I::TokenMaybe as MaybeOwned<'src, I::Token>>::Proj<Self::Token>;
type MaybeToken = <I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<Self::Token>;

type Cache = (I::Cache, S);

Expand All @@ -528,10 +488,10 @@ where
unsafe fn next_maybe(
(cache, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe> {
) -> Option<Self::MaybeToken> {
I::next_maybe(cache, &mut cursor.0).map(|tok| {
cursor.1 = Some(tok.borrow().1.end());
tok.choose(|(tok, _)| tok, |(tok, _)| tok)
tok.map_maybe(|(tok, _)| tok, |(tok, _)| tok)
})
}

Expand Down Expand Up @@ -644,7 +604,7 @@ where
type Span = S;

type Token = I::Token;
type TokenMaybe = I::TokenMaybe;
type MaybeToken = I::MaybeToken;

type Cache = (I::Cache, S::Context);

Expand All @@ -663,7 +623,7 @@ where
unsafe fn next_maybe(
(cache, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe> {
) -> Option<Self::MaybeToken> {
I::next_maybe(cache, cursor)
}

Expand Down Expand Up @@ -789,7 +749,7 @@ where
type Span = S;

type Token = I::Token;
type TokenMaybe = I::TokenMaybe;
type MaybeToken = I::MaybeToken;

type Cache = (I::Cache, F);

Expand All @@ -808,7 +768,7 @@ where
unsafe fn next_maybe(
(cache, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe> {
) -> Option<Self::MaybeToken> {
I::next_maybe(cache, cursor)
}

Expand Down Expand Up @@ -941,7 +901,7 @@ impl<'src, R: Read + Seek + 'src> Input<'src> for IoInput<R> {
type Span = SimpleSpan;

type Token = u8;
type TokenMaybe = u8;
type MaybeToken = u8;

type Cache = Self;

Expand All @@ -958,7 +918,7 @@ impl<'src, R: Read + Seek + 'src> Input<'src> for IoInput<R> {
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe> {
) -> Option<Self::MaybeToken> {
Self::next(this, cursor)
}

Expand Down Expand Up @@ -1347,7 +1307,7 @@ impl<'src, 'parse, I: Input<'src>, E: ParserExtra<'src, I>> InputRef<'src, 'pars
}

#[inline(always)]
pub(crate) fn next_maybe_inner(&mut self) -> Option<I::TokenMaybe> {
pub(crate) fn next_maybe_inner(&mut self) -> Option<I::MaybeToken> {
// SAFETY: cursor was generated by previous call to `Input::next`
let token = unsafe { I::next_maybe(self.cache, &mut self.cursor) };
if let Some(t) = &token {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ use self::{
recovery::{RecoverWith, Strategy},
span::Span,
text::*,
util::{MaybeMut, MaybeRef},
util::{IntoMaybe, MaybeMut, MaybeRef},
};
#[cfg(all(feature = "extension", doc))]
use self::{extension::v1::*, primitive::custom, stream::Stream};
Expand Down
8 changes: 4 additions & 4 deletions src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ where
type Span = SimpleSpan<usize>;

type Token = I::Item;
type TokenMaybe = I::Item;
type MaybeToken = I::Item;

type Cursor = usize;

Expand All @@ -87,7 +87,7 @@ where
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe> {
) -> Option<Self::MaybeToken> {
Self::next(this, cursor)
}

Expand Down Expand Up @@ -151,7 +151,7 @@ where
type Span = S;

type Token = T;
type TokenMaybe = T;
type MaybeToken = T;

type Cache = S; // eoi

Expand All @@ -168,7 +168,7 @@ where
unsafe fn next_maybe(
_eoi: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::TokenMaybe> {
) -> Option<Self::MaybeToken> {
cursor.0.next().map(|(tok, span)| {
cursor.1 += 1;
cursor.2 = Some(span.end());
Expand Down
4 changes: 2 additions & 2 deletions src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ where
pub fn digits<'a, C, I, E>(radix: u32) -> Repeated<impl Parser<'a, I, C, E> + Copy, C, I, E>
where
C: Char,
I: ValueInput<'a> + Input<'a, Token = C>,
I: ValueInput<'a, Token = C>,
E: ParserExtra<'a, I>,
{
any()
Expand Down Expand Up @@ -328,7 +328,7 @@ where
/// ```
///
#[must_use]
pub fn int<'a, I: ValueInput<'a> + StrInput<'a, C>, C: Char, E: ParserExtra<'a, I>>(
pub fn int<'a, I: StrInput<'a, C>, C: Char, E: ParserExtra<'a, I>>(
radix: u32,
) -> impl Parser<'a, I, &'a C::Str, E> + Copy {
any()
Expand Down
51 changes: 51 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,54 @@ impl<'de, T: Deserialize<'de>, R: Deref<Target = T>> Deserialize<'de> for Maybe<
deserializer.deserialize_newtype_struct("Maybe", MaybeVisitor(PhantomData))
}
}

mod ref_or_val_sealed {
pub trait Sealed<T> {}
}

/// An trait that allows abstracting over values of or references to a `T`.
///
/// Some [`Input`]s can only generate tokens by-reference (like `&[T]` -> `&T`), and some can only generate tokens
/// by-value (like `&str` -> `char`). This trait allows chumsky to handle both kinds of input.
///
/// The trait is sealed: you cannot implement it yourself.
pub trait IntoMaybe<'src, T: 'src>:
ref_or_val_sealed::Sealed<T> + Borrow<T> + Into<MaybeRef<'src, T>>
{
/// Project the referential properties of this type on to another type.
///
/// For example, `<&Foo>::Proj<Bar> = &Bar` but `<Foo>::Proj<Bar> = Bar`.
#[doc(hidden)]
type Proj<U: 'src>: IntoMaybe<'src, U>;

#[doc(hidden)]
fn map_maybe<R: 'src>(
self,
f: impl FnOnce(&'src T) -> &'src R,
g: impl FnOnce(T) -> R,
) -> Self::Proj<R>;
}

impl<T> ref_or_val_sealed::Sealed<T> for &T {}
impl<'src, T> IntoMaybe<'src, T> for &'src T {
type Proj<U: 'src> = &'src U;
fn map_maybe<R: 'src>(
self,
f: impl FnOnce(&'src T) -> &'src R,
_g: impl FnOnce(T) -> R,
) -> Self::Proj<R> {
f(self)
}
}

impl<T> ref_or_val_sealed::Sealed<T> for T {}
impl<'src, T: 'src> IntoMaybe<'src, T> for T {
type Proj<U: 'src> = U;
fn map_maybe<R: 'src>(
self,
_f: impl FnOnce(&'src T) -> &'src R,
g: impl FnOnce(T) -> R,
) -> Self::Proj<R> {
g(self)
}
}

0 comments on commit 9d31654

Please sign in to comment.