tinymist_world/font/
slot.rs

1use core::fmt;
2use std::sync::Arc;
3
4use tinymist_std::debug_loc::DataSource;
5use tinymist_std::QueryRef;
6use typst::text::Font;
7
8use crate::font::FontLoader;
9
10type FontSlotInner = QueryRef<Option<Font>, (), Box<dyn FontLoader + Send>>;
11
12/// Lazy Font Reference, load as needed.
13pub struct FontSlot {
14    inner: FontSlotInner,
15    pub description: Option<Arc<DataSource>>,
16}
17
18impl FontSlot {
19    pub fn with_value(f: Option<Font>) -> Self {
20        Self {
21            inner: FontSlotInner::with_value(f),
22            description: None,
23        }
24    }
25
26    pub fn new(f: Box<dyn FontLoader + Send>) -> Self {
27        Self {
28            inner: FontSlotInner::with_context(f),
29            description: None,
30        }
31    }
32
33    pub fn new_boxed<F: FontLoader + Send + 'static>(f: F) -> Self {
34        Self::new(Box::new(f))
35    }
36
37    pub fn describe(self, desc: DataSource) -> Self {
38        Self {
39            inner: self.inner,
40            description: Some(Arc::new(desc)),
41        }
42    }
43
44    /// Gets the reference to the font load result (possible uninitialized).
45    ///
46    /// Returns `None` if the cell is empty, or being initialized. This
47    /// method never blocks.
48    pub fn get_uninitialized(&self) -> Option<Option<Font>> {
49        self.inner
50            .get_uninitialized()
51            .cloned()
52            .map(|e| e.ok().flatten())
53    }
54
55    /// Gets or make the font load result.
56    pub fn get_or_init(&self) -> Option<Font> {
57        let res = self.inner.compute_with_context(|mut c| Ok(c.load()));
58        res.unwrap().clone()
59    }
60}
61
62impl fmt::Debug for FontSlot {
63    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64        f.debug_tuple("FontSlot")
65            .field(&self.get_uninitialized())
66            .finish()
67    }
68}