pub trait Source {
type Slice: ?Sized + PartialEq + Eq + Debug;
// Required methods
fn len(&self) -> usize;
fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>
where Chunk: Chunk<'a>;
unsafe fn read_unchecked<'a, Chunk>(&'a self, offset: usize) -> 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.
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 boundsSourceunsafe fn read_unchecked<'a, Chunk>(&'a self, offset: usize) -> Chunkwhere
Chunk: Chunk<'a>,
unsafe fn read_unchecked<'a, Chunk>(&'a self, offset: usize) -> Chunkwhere
Chunk: Chunk<'a>,
Read a chunk of bytes into an array without doing bounds checks.
Sourcefn 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
unsafe fn slice_unchecked(&self, range: Range<usize>) -> &Self::Slice
Get a slice of the source at given range. This is analogous to
slice::get_unchecked(range).
Using this method with range out of bounds is undefined behavior!
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.