tinymist_world/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//! World implementation of typst for tinymist.

#![allow(missing_docs)]

pub mod args;
pub mod config;
pub mod debug_loc;
pub mod entry;
pub mod font;
pub mod package;
pub mod parser;
pub mod source;
pub mod world;

pub use compute::*;
pub use entry::*;
pub use snapshot::*;
pub use world::*;

pub use tinymist_vfs as vfs;

mod compute;
mod snapshot;

/// Run the compiler in the system environment.
#[cfg(feature = "system")]
pub mod system;
#[cfg(feature = "system")]
pub use system::{print_diagnostics, SystemCompilerFeat, TypstSystemUniverse, TypstSystemWorld};

/// Run the compiler in the browser environment.
#[cfg(feature = "browser")]
pub(crate) mod browser;
#[cfg(feature = "browser")]
pub use browser::{BrowserCompilerFeat, TypstBrowserUniverse, TypstBrowserWorld};

use std::{path::Path, sync::Arc};

use ecow::EcoVec;
use tinymist_vfs::PathAccessModel as VfsAccessModel;
use typst::diag::{At, FileResult, SourceResult};
use typst::foundations::Bytes;
use typst::syntax::{FileId, Span};

use font::FontResolver;
use package::PackageRegistry;

/// Latest version of the shadow api, which is in beta.
pub trait ShadowApi {
    /// Get the shadow files.
    fn shadow_paths(&self) -> Vec<Arc<Path>>;
    /// Get the shadow files by file id.
    fn shadow_ids(&self) -> Vec<FileId>;

    /// Reset the shadow files.
    fn reset_shadow(&mut self) {
        for path in self.shadow_paths() {
            self.unmap_shadow(&path).unwrap();
        }
    }

    /// Add a shadow file to the driver.
    fn map_shadow(&mut self, path: &Path, content: Bytes) -> FileResult<()>;

    /// Add a shadow file to the driver.
    fn unmap_shadow(&mut self, path: &Path) -> FileResult<()>;

    /// Add a shadow file to the driver by file id.
    /// Note: If a *path* is both shadowed by id and by path, the shadow by id
    /// will be used.
    fn map_shadow_by_id(&mut self, file_id: FileId, content: Bytes) -> FileResult<()>;

    /// Add a shadow file to the driver by file id.
    /// Note: If a *path* is both shadowed by id and by path, the shadow by id
    /// will be used.
    fn unmap_shadow_by_id(&mut self, file_id: FileId) -> FileResult<()>;
}

pub trait ShadowApiExt {
    /// Wrap the driver with a given shadow file and run the inner function.
    fn with_shadow_file<T>(
        &mut self,
        file_path: &Path,
        content: Bytes,
        f: impl FnOnce(&mut Self) -> SourceResult<T>,
    ) -> SourceResult<T>;

    /// Wrap the driver with a given shadow file and run the inner function by
    /// file id.
    /// Note: to enable this function, `ShadowApi` must implement
    /// `_shadow_map_id`.
    fn with_shadow_file_by_id<T>(
        &mut self,
        file_id: FileId,
        content: Bytes,
        f: impl FnOnce(&mut Self) -> SourceResult<T>,
    ) -> SourceResult<T>;
}

impl<C: ShadowApi> ShadowApiExt for C {
    /// Wrap the driver with a given shadow file and run the inner function.
    fn with_shadow_file<T>(
        &mut self,
        file_path: &Path,
        content: Bytes,
        f: impl FnOnce(&mut Self) -> SourceResult<T>,
    ) -> SourceResult<T> {
        self.map_shadow(file_path, content).at(Span::detached())?;
        let res: Result<T, EcoVec<typst::diag::SourceDiagnostic>> = f(self);
        self.unmap_shadow(file_path).at(Span::detached())?;
        res
    }

    /// Wrap the driver with a given shadow file and run the inner function by
    /// file id.
    /// Note: to enable this function, `ShadowApi` must implement
    /// `_shadow_map_id`.
    fn with_shadow_file_by_id<T>(
        &mut self,
        file_id: FileId,
        content: Bytes,
        f: impl FnOnce(&mut Self) -> SourceResult<T>,
    ) -> SourceResult<T> {
        self.map_shadow_by_id(file_id, content)
            .at(Span::detached())?;
        let res: Result<T, EcoVec<typst::diag::SourceDiagnostic>> = f(self);
        self.unmap_shadow_by_id(file_id).at(Span::detached())?;
        res
    }
}

/// Latest version of the world dependencies api, which is in beta.
pub trait WorldDeps {
    fn iter_dependencies(&self, f: &mut dyn FnMut(FileId));
}

/// type trait interface of [`CompilerWorld`].
pub trait CompilerFeat: Send + Sync + 'static {
    /// Specify the font resolver for typst compiler.
    type FontResolver: FontResolver + Send + Sync + Sized;
    /// Specify the access model for VFS.
    type AccessModel: VfsAccessModel + Clone + Send + Sync + Sized;
    /// Specify the package registry.
    type Registry: PackageRegistry + Send + Sync + Sized;
}

/// Which format to use for diagnostics.
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd)]
pub enum DiagnosticFormat {
    #[default]
    Human,
    Short,
}

pub mod build_info {
    /// The version of the reflexo-world crate.
    pub static VERSION: &str = env!("CARGO_PKG_VERSION");
}