Minor docs additions

This commit is contained in:
Laurenz 2025-06-10 14:35:01 +02:00
parent a8a2014422
commit 8f192678b2
3 changed files with 24 additions and 11 deletions

View File

@ -571,22 +571,27 @@ impl From<PackageError> for EcoString {
} }
} }
/// A result type with a data-loading-related error.
pub type LoadResult<T> = Result<T, LoadError>; pub type LoadResult<T> = Result<T, LoadError>;
/// A call site independent error that occurred during data loading. /// A call site independent error that occurred during data loading. This avoids
/// This avoids polluting the memoization with [`Span`]s and [`FileId`]s from source files. /// polluting the memoization with [`Span`]s and [`FileId`]s from source files.
/// Can be turned into a [`SourceDiagnostic`] using the [`LoadedWithin::within`] method /// Can be turned into a [`SourceDiagnostic`] using the [`LoadedWithin::within`]
/// available on [`LoadResult`]. /// method available on [`LoadResult`].
/// ///
/// [`FileId`]: typst_syntax::FileId /// [`FileId`]: typst_syntax::FileId
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct LoadError { pub struct LoadError {
/// The position in the file at which the error occured.
pos: ReportPos, pos: ReportPos,
/// Must contain a message formatted like this: `"failed to do thing (cause)"`. /// Must contain a message formatted like this: `"failed to do thing (cause)"`.
message: EcoString, message: EcoString,
} }
impl LoadError { impl LoadError {
/// Creates a new error from a position in a file, a base message
/// (e.g. `failed to parse JSON`) and a concrete error (e.g. `invalid
/// number`)
pub fn new( pub fn new(
pos: impl Into<ReportPos>, pos: impl Into<ReportPos>,
message: impl std::fmt::Display, message: impl std::fmt::Display,
@ -611,7 +616,8 @@ impl From<Utf8Error> for LoadError {
} }
} }
/// Convert a [`LoadResult`] to a [`SourceResult`] by adding the [`Loaded`] context. /// Convert a [`LoadResult`] to a [`SourceResult`] by adding the [`Loaded`]
/// context.
pub trait LoadedWithin<T> { pub trait LoadedWithin<T> {
/// Report an error, possibly in an external file. /// Report an error, possibly in an external file.
fn within(self, loaded: &Loaded) -> SourceResult<T>; fn within(self, loaded: &Loaded) -> SourceResult<T>;
@ -706,6 +712,7 @@ fn load_err_in_invalid_text(
eco_vec![SourceDiagnostic::error(loaded.source.span, message)] eco_vec![SourceDiagnostic::error(loaded.source.span, message)]
} }
/// A position at which an error was reported.
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub enum ReportPos { pub enum ReportPos {
/// Contains a range, and a line/column pair. /// Contains a range, and a line/column pair.
@ -731,11 +738,13 @@ impl From<LineCol> for ReportPos {
} }
impl ReportPos { impl ReportPos {
/// Creates a position from a pre-existing range and line-column pair.
pub fn full(range: std::ops::Range<usize>, pair: LineCol) -> Self { pub fn full(range: std::ops::Range<usize>, pair: LineCol) -> Self {
let range = range.start.saturating_as()..range.end.saturating_as(); let range = range.start.saturating_as()..range.end.saturating_as();
Self::Full(range, pair) Self::Full(range, pair)
} }
/// Tries to determine the byte range for this position.
fn range(&self, lines: &Lines<String>) -> Option<std::ops::Range<usize>> { fn range(&self, lines: &Lines<String>) -> Option<std::ops::Range<usize>> {
match self { match self {
ReportPos::Full(range, _) => Some(range.start as usize..range.end as usize), ReportPos::Full(range, _) => Some(range.start as usize..range.end as usize),
@ -749,6 +758,7 @@ impl ReportPos {
} }
} }
/// Tries to determine the line/column for this position.
fn line_col(&self, lines: &Lines<String>) -> Option<LineCol> { fn line_col(&self, lines: &Lines<String>) -> Option<LineCol> {
match self { match self {
&ReportPos::Full(_, pair) => Some(pair), &ReportPos::Full(_, pair) => Some(pair),
@ -761,7 +771,7 @@ impl ReportPos {
} }
} }
/// Either get the the line/column pair, or try to compute it from possibly /// Either gets the line/column pair, or tries to compute it from possibly
/// invalid utf-8 data. /// invalid utf-8 data.
fn try_line_col(&self, bytes: &[u8]) -> Option<LineCol> { fn try_line_col(&self, bytes: &[u8]) -> Option<LineCol> {
match self { match self {

View File

@ -27,7 +27,7 @@ pub use self::toml_::*;
pub use self::xml_::*; pub use self::xml_::*;
pub use self::yaml_::*; pub use self::yaml_::*;
use crate::diag::{At, LoadedWithin, SourceResult}; use crate::diag::{At, SourceResult};
use crate::foundations::OneOrMultiple; use crate::foundations::OneOrMultiple;
use crate::foundations::{cast, Bytes, Scope, Str}; use crate::foundations::{cast, Bytes, Scope, Str};
use crate::World; use crate::World;
@ -88,13 +88,13 @@ impl Load for Spanned<&DataSource> {
match &self.v { match &self.v {
DataSource::Path(path) => { DataSource::Path(path) => {
let file_id = self.span.resolve_path(path).at(self.span)?; let file_id = self.span.resolve_path(path).at(self.span)?;
let bytes = world.file(file_id).at(self.span)?; let data = world.file(file_id).at(self.span)?;
let source = Spanned::new(LoadSource::Path(file_id), self.span); let source = Spanned::new(LoadSource::Path(file_id), self.span);
Ok(Loaded::new(source, bytes)) Ok(Loaded::new(source, data))
} }
DataSource::Bytes(bytes) => { DataSource::Bytes(data) => {
let source = Spanned::new(LoadSource::Bytes, self.span); let source = Spanned::new(LoadSource::Bytes, self.span);
Ok(Loaded::new(source, bytes.clone())) Ok(Loaded::new(source, data.clone()))
} }
} }
} }
@ -123,7 +123,9 @@ impl Load for Spanned<&OneOrMultiple<DataSource>> {
/// Data loaded from a [`DataSource`]. /// Data loaded from a [`DataSource`].
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Loaded { pub struct Loaded {
/// Details about where `data` was loaded from.
pub source: Spanned<LoadSource>, pub source: Spanned<LoadSource>,
/// The loaded data.
pub data: Bytes, pub data: Bytes,
} }

View File

@ -77,6 +77,7 @@ impl yaml {
} }
} }
/// Format the user-facing YAML error message.
pub fn format_yaml_error(error: serde_yaml::Error) -> LoadError { pub fn format_yaml_error(error: serde_yaml::Error) -> LoadError {
let pos = error let pos = error
.location() .location()