Rust implementation of NextGraph, a Decentralized and local-first web 3.0 ecosystem
https://nextgraph.org
byzantine-fault-tolerancecrdtsdappsdecentralizede2eeeventual-consistencyjson-ldlocal-firstmarkdownocapoffline-firstp2pp2p-networkprivacy-protectionrdfrich-text-editorself-hostedsemantic-websparqlweb3collaboration
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.8 KiB
97 lines
2.8 KiB
use std::ops::Range;
|
|
use std::{fmt, io};
|
|
|
|
/// A position in a text i.e. a `line` number starting from 0, a `column` number starting from 0 (in number of code points) and a global file `offset` starting from 0 (in number of bytes).
|
|
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
|
|
pub struct TextPosition {
|
|
pub line: u64,
|
|
pub column: u64,
|
|
pub offset: u64,
|
|
}
|
|
|
|
/// An error in the syntax of the parsed file.
|
|
///
|
|
/// It is composed of a message and a byte range in the input.
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub struct TurtleSyntaxError {
|
|
pub(super) location: Range<TextPosition>,
|
|
pub(super) message: String,
|
|
}
|
|
|
|
impl TurtleSyntaxError {
|
|
/// The location of the error inside of the file.
|
|
#[inline]
|
|
pub fn location(&self) -> Range<TextPosition> {
|
|
self.location.clone()
|
|
}
|
|
|
|
/// The error message.
|
|
#[inline]
|
|
pub fn message(&self) -> &str {
|
|
&self.message
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for TurtleSyntaxError {
|
|
#[inline]
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
if self.location.start.offset + 1 >= self.location.end.offset {
|
|
write!(
|
|
f,
|
|
"Parser error at line {} column {}: {}",
|
|
self.location.start.line + 1,
|
|
self.location.start.column + 1,
|
|
self.message
|
|
)
|
|
} else if self.location.start.line == self.location.end.line {
|
|
write!(
|
|
f,
|
|
"Parser error between at line {} between columns {} and column {}: {}",
|
|
self.location.start.line + 1,
|
|
self.location.start.column + 1,
|
|
self.location.end.column + 1,
|
|
self.message
|
|
)
|
|
} else {
|
|
write!(
|
|
f,
|
|
"Parser error between line {} column {} and line {} column {}: {}",
|
|
self.location.start.line + 1,
|
|
self.location.start.column + 1,
|
|
self.location.end.line + 1,
|
|
self.location.end.column + 1,
|
|
self.message
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<TurtleSyntaxError> for io::Error {
|
|
#[inline]
|
|
fn from(error: TurtleSyntaxError) -> Self {
|
|
Self::new(io::ErrorKind::InvalidData, error)
|
|
}
|
|
}
|
|
|
|
/// A parsing error.
|
|
///
|
|
/// It is the union of [`TurtleSyntaxError`] and [`io::Error`].
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum TurtleParseError {
|
|
/// I/O error during parsing (file not found...).
|
|
#[error(transparent)]
|
|
Io(#[from] io::Error),
|
|
/// An error in the file syntax.
|
|
#[error(transparent)]
|
|
Syntax(#[from] TurtleSyntaxError),
|
|
}
|
|
|
|
impl From<TurtleParseError> for io::Error {
|
|
#[inline]
|
|
fn from(error: TurtleParseError) -> Self {
|
|
match error {
|
|
TurtleParseError::Syntax(e) => e.into(),
|
|
TurtleParseError::Io(e) => e,
|
|
}
|
|
}
|
|
}
|
|
|