diff options
Diffstat (limited to 'src/parse/span.rs')
| -rw-r--r-- | src/parse/span.rs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/parse/span.rs b/src/parse/span.rs new file mode 100644 index 0000000..340a078 --- /dev/null +++ b/src/parse/span.rs @@ -0,0 +1,86 @@ +use std::sync::atomic::AtomicU32; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct FileId { + id: u32, +} + +impl FileId { + pub fn new() -> Self { + static GEN: AtomicU32 = AtomicU32::new(0); + Self { + id: GEN.fetch_add(1, std::sync::atomic::Ordering::SeqCst), + } + } + + pub fn from(self, start: u32) -> SpanFrom { + SpanFrom::new(self, start) + } + + pub fn span(self, start: u32, end: u32) -> Span { + Span::new(self, start, end) + } +} + +#[derive(Copy, Clone)] +pub struct SpanFrom { + pub file: FileId, + pub start: u32, +} + +impl SpanFrom { + pub fn new(file: FileId, start: u32) -> Self { + Self { file, start } + } + + pub fn to(self, end: u32) -> Span { + Span::new(self.file, self.start, end) + } + + pub fn with_len(self, len: u32) -> Span { + self.to(self.start + len) + } +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct Span { + pub file: FileId, + pub start: u32, + pub end: u32, +} + +/// manual implementation of PartialOrd to ensure shorter Spans are first +impl PartialOrd for Span { + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + match self.file.partial_cmp(&other.file) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.start.partial_cmp(&other.start) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + other.end.partial_cmp(&self.end) + } +} + +/// manual implementation of Ord to ensure shorter Spans are first +impl Ord for Span { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match self.file.cmp(&other.file) { + core::cmp::Ordering::Equal => {} + ord => return ord, + } + match self.start.cmp(&other.start) { + core::cmp::Ordering::Equal => {} + ord => return ord, + } + other.end.cmp(&self.end) + } +} + +impl Span { + pub fn new(file: FileId, start: u32, end: u32) -> Self { + Self { file, start, end } + } +} |
