56 lines
1.3 KiB
Rust
56 lines
1.3 KiB
Rust
|
use core::{fmt, ops::Deref};
|
||
|
|
||
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||
|
pub struct Span {
|
||
|
pub start: u32,
|
||
|
pub end: u32,
|
||
|
}
|
||
|
|
||
|
impl Span {
|
||
|
pub fn new(start: u32, end: u32) -> Self {
|
||
|
Self { start, end }
|
||
|
}
|
||
|
|
||
|
pub fn slice<'a>(&self, source: &'a SourceCode) -> &'a str {
|
||
|
&source.code[self.start as usize..self.end as usize]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl fmt::Debug for Span {
|
||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||
|
write!(f, "{}..{}", self.start, self.end)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Source code string with a verified size limit.
|
||
|
/// An exact size limit is not enforced by this type - it only ensures the string isn't longer than
|
||
|
/// intended, to not stall the parser for an unexpected amount of time.
|
||
|
#[derive(Debug, PartialEq, Eq)]
|
||
|
#[repr(transparent)]
|
||
|
pub struct SourceCode {
|
||
|
code: str,
|
||
|
}
|
||
|
|
||
|
impl SourceCode {
|
||
|
pub fn limited_len(code: &str, max_len: u32) -> Option<&Self> {
|
||
|
if code.len() <= max_len as usize {
|
||
|
Some(Self::unlimited_len(code))
|
||
|
} else {
|
||
|
None
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn unlimited_len(code: &str) -> &Self {
|
||
|
// SAFETY: SourceCode is a transparent wrapper around str, so converting between them is safe.
|
||
|
unsafe { core::mem::transmute(code) }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Deref for SourceCode {
|
||
|
type Target = str;
|
||
|
|
||
|
fn deref(&self) -> &Self::Target {
|
||
|
&self.code
|
||
|
}
|
||
|
}
|