Skip to main content

webfont_generator/
hooks.rs

1//! Runtime-independent asynchronous callbacks for language adapters.
2use std::future::Future;
3
4use serde_json::{Map, Value};
5
6/// Async hooks used by [`crate::generate_with_hooks`].
7///
8/// Rename receives ordered paths after source loading, flattened in configured variant order.
9/// Return `None` to derive names from file stems. Context hooks run only when their matching
10/// `has_*_context` method returns true; CSS runs before HTML. Callback errors are preserved
11/// through the associated error type, while engine failures are converted from I/O errors.
12pub trait GenerationHooks: Send + Sync {
13    /// Error returned to the caller, including converted engine errors.
14    type Error: From<std::io::Error> + Send;
15
16    /// Resolve one glyph name per borrowed path, or use the engine's defaults.
17    /// Adapters that need an owned callback payload can copy paths inside this method.
18    fn rename(
19        &self,
20        _paths: &[String],
21    ) -> impl Future<Output = Result<Option<Vec<String>>, Self::Error>> + Send {
22        async { Ok(None) }
23    }
24
25    /// Whether CSS context mutation is enabled.
26    fn has_css_context(&self) -> bool {
27        false
28    }
29
30    /// Whether HTML context mutation is enabled.
31    fn has_html_context(&self) -> bool {
32        false
33    }
34
35    /// Mutate the CSS template context before rendering.
36    fn css_context(
37        &self,
38        context: Map<String, Value>,
39    ) -> impl Future<Output = Result<Map<String, Value>, Self::Error>> + Send {
40        async { Ok(context) }
41    }
42
43    /// Mutate the HTML context, including styles derived from the finalized CSS context.
44    fn html_context(
45        &self,
46        context: Map<String, Value>,
47    ) -> impl Future<Output = Result<Map<String, Value>, Self::Error>> + Send {
48        async { Ok(context) }
49    }
50}
51
52impl GenerationHooks for () {
53    type Error = std::io::Error;
54}
55
56/// Adapt the existing synchronous Rust rename callback without copying input paths.
57pub(crate) struct RenameHooks<'a>(pub Option<&'a (dyn Fn(&str) -> String + Send + Sync)>);
58
59impl GenerationHooks for RenameHooks<'_> {
60    type Error = std::io::Error;
61
62    async fn rename(&self, paths: &[String]) -> std::io::Result<Option<Vec<String>>> {
63        Ok(self
64            .0
65            .map(|rename| paths.iter().map(|path| rename(path)).collect()))
66    }
67}