use core::fmt;
use typst::diag::{FileError, FileResult};
use crate::{Bytes, ImmutPath};
#[derive(Clone, PartialEq, Eq)]
pub struct FileSnapshot(Result<Bytes, Box<FileError>>);
#[derive(Debug)]
#[allow(dead_code)]
struct FileContent {
len: usize,
}
impl fmt::Debug for FileSnapshot {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0.as_ref() {
Ok(v) => f
.debug_struct("FileSnapshot")
.field("content", &FileContent { len: v.len() })
.finish(),
Err(e) => f.debug_struct("FileSnapshot").field("error", &e).finish(),
}
}
}
impl FileSnapshot {
#[inline]
#[track_caller]
pub fn content(&self) -> FileResult<&Bytes> {
self.0.as_ref().map_err(|e| *e.clone())
}
#[inline]
#[track_caller]
pub fn is_file(&self) -> FileResult<bool> {
self.content().map(|_| true)
}
}
impl std::ops::Deref for FileSnapshot {
type Target = Result<Bytes, Box<FileError>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::ops::DerefMut for FileSnapshot {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<FileResult<Bytes>> for FileSnapshot {
fn from(result: FileResult<Bytes>) -> Self {
Self(result.map_err(Box::new))
}
}
#[derive(Debug, Clone, Default)]
pub struct FileChangeSet {
pub removes: Vec<ImmutPath>,
pub inserts: Vec<(ImmutPath, FileSnapshot)>,
}
impl FileChangeSet {
pub fn is_empty(&self) -> bool {
self.inserts.is_empty() && self.removes.is_empty()
}
pub fn new_removes(removes: Vec<ImmutPath>) -> Self {
Self {
removes,
inserts: vec![],
}
}
pub fn new_inserts(inserts: Vec<(ImmutPath, FileSnapshot)>) -> Self {
Self {
removes: vec![],
inserts,
}
}
pub fn may_insert(&mut self, v: Option<(ImmutPath, FileSnapshot)>) {
if let Some(v) = v {
self.inserts.push(v);
}
}
pub fn may_extend(&mut self, v: Option<impl Iterator<Item = (ImmutPath, FileSnapshot)>>) {
if let Some(v) = v {
self.inserts.extend(v);
}
}
}