pub trait Source {
type Slice<'a>: PartialEq + Eq + Debug
where Self: 'a;
// Required methods
fn len(&self) -> usize;
fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>
where Chunk: Chunk<'a>;
fn slice(&self, range: Range<usize>) -> Option<Self::Slice<'_>>;
unsafe fn slice_unchecked(&self, range: Range<usize>) -> Self::Slice<'_>;
fn is_boundary(&self, index: usize) -> bool;
// Provided method
fn find_boundary(&self, index: usize) -> usize { ... }
}Expand description
Trait for types the Lexer can read from.
Most notably this is implemented for &str. It is unlikely you will
ever want to use this Trait yourself, unless implementing a new Source
the Lexer can use.
SAFETY: Unless the unsafe functions of this trait are disabled with the forbid_unsafe
feature, the correctness of the unsafe functions of this trait depend on the correct
implementation of the len and find_boundary functions so generated code does not request
out-of-bounds access.
Required Associated Types§
Required Methods§
Sourcefn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>where
Chunk: Chunk<'a>,
fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>where
Chunk: Chunk<'a>,
Read a chunk of bytes into an array. Returns None when reading
out of bounds would occur.
This is very useful for matching fixed-size byte arrays, and tends to be very fast at it too, since the compiler knows the byte lengths.
use logos::Source;
let foo = "foo";
assert_eq!(foo.read(0), Some(b"foo")); // Option<&[u8; 3]>
assert_eq!(foo.read(0), Some(b"fo")); // Option<&[u8; 2]>
assert_eq!(foo.read(2), Some(b'o')); // Option<u8>
assert_eq!(foo.read::<&[u8; 4]>(0), None); // Out of bounds
assert_eq!(foo.read::<&[u8; 2]>(2), None); // Out of boundsSourcefn slice(&self, range: Range<usize>) -> Option<Self::Slice<'_>>
fn slice(&self, range: Range<usize>) -> Option<Self::Slice<'_>>
Get a slice of the source at given range. This is analogous to
slice::get(range).
use logos::Source;
let foo = "It was the year when they finally immanentized the Eschaton.";
assert_eq!(<str as Source>::slice(&foo, 51..59), Some("Eschaton"));Sourceunsafe fn slice_unchecked(&self, range: Range<usize>) -> Self::Slice<'_>
Available on non-crate feature forbid_unsafe only.
unsafe fn slice_unchecked(&self, range: Range<usize>) -> Self::Slice<'_>
forbid_unsafe only.Get a slice of the source at given range. This is analogous to
slice::get_unchecked(range).
§Safety
Range should not exceed bounds.
use logos::Source;
let foo = "It was the year when they finally immanentized the Eschaton.";
unsafe {
assert_eq!(<str as Source>::slice_unchecked(&foo, 51..59), "Eschaton");
}Sourcefn is_boundary(&self, index: usize) -> bool
fn is_boundary(&self, index: usize) -> bool
Check if index is valid for this Source, that is:
- It’s not larger than the byte length of the
Source. - (
stronly) It doesn’t land in the middle of a UTF-8 code point.
Provided Methods§
Sourcefn find_boundary(&self, index: usize) -> usize
fn find_boundary(&self, index: usize) -> usize
For &str sources attempts to find the closest char boundary at which source
can be sliced, starting from index.
For binary sources (&[u8]) this should just return index back.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementations on Foreign Types§
Source§impl Source for str
impl Source for str
type Slice<'a> = &'a str
fn len(&self) -> usize
fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>where
Chunk: Chunk<'a>,
fn slice(&self, range: Range<usize>) -> Option<&str>
Source§unsafe fn slice_unchecked(&self, range: Range<usize>) -> &str
unsafe fn slice_unchecked(&self, range: Range<usize>) -> &str
forbid_unsafe only.fn find_boundary(&self, index: usize) -> usize
fn is_boundary(&self, index: usize) -> bool
Source§impl Source for [u8]
impl Source for [u8]
type Slice<'a> = &'a [u8]
fn len(&self) -> usize
fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>where
Chunk: Chunk<'a>,
fn slice(&self, range: Range<usize>) -> Option<&[u8]>
Source§unsafe fn slice_unchecked(&self, range: Range<usize>) -> &[u8] ⓘ
unsafe fn slice_unchecked(&self, range: Range<usize>) -> &[u8] ⓘ
forbid_unsafe only.