From f18ccc1f198caa0912847f841e1dc2203dfffd1d Mon Sep 17 00:00:00 2001 From: Myriad-Dreamin Date: Thu, 28 Sep 2023 20:15:54 +0800 Subject: [PATCH] dev(compiler): box file error --- compiler/src/service/watch.rs | 4 ++-- compiler/src/vfs/notify.rs | 39 +++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/compiler/src/service/watch.rs b/compiler/src/service/watch.rs index d547c475..494ad1c2 100644 --- a/compiler/src/service/watch.rs +++ b/compiler/src/service/watch.rs @@ -18,14 +18,14 @@ use typst::diag::{FileError, FileResult}; use typst_ts_core::{Bytes, ImmutPath}; use crate::vfs::{ - notify::{FileChangeSet, FilesystemEvent, NotifyFile, NotifyMessage, UpstreamUpdateEvent}, + notify::{FileChangeSet, FileSnapshot, FilesystemEvent, NotifyMessage, UpstreamUpdateEvent}, system::SystemAccessModel, AccessModel, }; type WatcherPair = (RecommendedWatcher, mpsc::UnboundedReceiver); type NotifyEvent = notify::Result; -type FileEntry = (/* key */ ImmutPath, /* value */ NotifyFile); +type FileEntry = (/* key */ ImmutPath, /* value */ FileSnapshot); type NotifyFilePair = FileResult<( /* mtime */ instant::SystemTime, /* content */ Bytes, diff --git a/compiler/src/vfs/notify.rs b/compiler/src/vfs/notify.rs index 7a493f70..a196adb9 100644 --- a/compiler/src/vfs/notify.rs +++ b/compiler/src/vfs/notify.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, path::Path}; -use typst::diag::FileResult; +use typst::diag::{FileError, FileResult}; use typst_ts_core::{Bytes, ImmutPath}; use crate::vfs::AccessModel; @@ -13,30 +13,43 @@ struct NotifyFileRepr { } /// A file snapshot that is notified by some external source +/// +/// Note: The error is boxed to avoid large stack size #[derive(Debug, Clone)] -pub struct NotifyFile(FileResult); +pub struct FileSnapshot(Result>); + +impl FileSnapshot { + /// Access the internal data of the file snapshot + #[inline] + #[track_caller] + fn retrieve<'a, T>(&'a self, f: impl FnOnce(&'a NotifyFileRepr) -> T) -> FileResult { + self.0.as_ref().map(f).map_err(|e| *e.clone()) + } -impl NotifyFile { /// mtime of the file pub fn mtime(&self) -> FileResult<&instant::SystemTime> { - self.0.as_ref().map(|e| &e.mtime).map_err(|e| e.clone()) + self.retrieve(|e| &e.mtime) } /// content of the file pub fn content(&self) -> FileResult<&Bytes> { - self.0.as_ref().map(|e| &e.content).map_err(|e| e.clone()) + self.retrieve(|e| &e.content) } /// Whether the related file is a file pub fn is_file(&self) -> FileResult { - self.0.as_ref().map(|_| true).map_err(|e| e.clone()) + self.retrieve(|_| true) } } /// Convenent function to create a [`NotifyFile`] from tuple -impl From> for NotifyFile { +impl From> for FileSnapshot { fn from(result: FileResult<(instant::SystemTime, Bytes)>) -> Self { - Self(result.map(|(mtime, content)| NotifyFileRepr { mtime, content })) + Self( + result + .map(|(mtime, content)| NotifyFileRepr { mtime, content }) + .map_err(Box::new), + ) } } @@ -50,7 +63,7 @@ pub struct FileChangeSet { /// Files to remove pub removes: Vec, /// Files to insert or update - pub inserts: Vec<(ImmutPath, NotifyFile)>, + pub inserts: Vec<(ImmutPath, FileSnapshot)>, } impl FileChangeSet { @@ -68,7 +81,7 @@ impl FileChangeSet { } /// Create a new changeset with inserting files - pub fn new_inserts(inserts: Vec<(ImmutPath, NotifyFile)>) -> Self { + pub fn new_inserts(inserts: Vec<(ImmutPath, FileSnapshot)>) -> Self { Self { removes: vec![], inserts, @@ -76,14 +89,14 @@ impl FileChangeSet { } /// Utility function to insert a possible file to insert or update - pub fn may_insert(&mut self, v: Option<(ImmutPath, NotifyFile)>) { + pub fn may_insert(&mut self, v: Option<(ImmutPath, FileSnapshot)>) { if let Some(v) = v { self.inserts.push(v); } } /// Utility function to insert multiple possible files to insert or update - pub fn may_extend(&mut self, v: Option>) { + pub fn may_extend(&mut self, v: Option>) { if let Some(v) = v { self.inserts.extend(v); } @@ -167,7 +180,7 @@ pub enum NotifyMessage { /// Notify shadowing access model, which the typical underlying access model is /// [`crate::vfs::system::SystemAccessModel`] pub struct NotifyAccessModel { - files: HashMap, + files: HashMap, pub inner: M, }