starship/modules/
typst.rs1use super::{Context, Module, ModuleConfig};
2
3use crate::configs::typst::TypstConfig;
4use crate::formatter::{StringFormatter, VersionFormatter};
5
6pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
8 let mut module = context.new_module("typst");
9 let config = TypstConfig::try_load(module.config);
10
11 let is_typst_project = context
12 .try_begin_scan()?
13 .set_files(&config.detect_files)
14 .set_extensions(&config.detect_extensions)
15 .set_folders(&config.detect_folders)
16 .is_match();
17
18 if !is_typst_project {
19 return None;
20 }
21
22 let parsed = StringFormatter::new(config.format).and_then(|formatter| {
23 formatter
24 .map_meta(|var, _| match var {
25 "symbol" => Some(config.symbol),
26 _ => None,
27 })
28 .map_style(|variable| match variable {
29 "style" => Some(Ok(config.style)),
30 _ => None,
31 })
32 .map(|variable| match variable {
33 "version" => {
34 let version = get_typst_config(context)?;
35 VersionFormatter::format_module_version(
36 module.get_name(),
37 &version,
38 config.version_format,
39 )
40 .map(Ok)
41 }
42 _ => None,
43 })
44 .parse(None, Some(context))
45 });
46
47 module.set_segments(match parsed {
48 Ok(segments) => segments,
49 Err(error) => {
50 log::warn!("Error in module `typst`:\n{error}");
51 return None;
52 }
53 });
54
55 Some(module)
56}
57
58fn get_typst_config(context: &Context) -> Option<String> {
59 context
60 .exec_cmd("typst", &["--version"])?
61 .stdout
62 .trim()
63 .strip_prefix("typst ")
64 .and_then(|version| version.split_whitespace().next().map(ToOwned::to_owned))
65}
66
67#[cfg(test)]
68mod tests {
69 use crate::test::ModuleRenderer;
70 use nu_ansi_term::Color;
71 use std::fs::File;
72 use std::io;
73 #[test]
74 fn read_typst_not_present() -> io::Result<()> {
75 let dir = tempfile::tempdir()?;
76
77 let actual = ModuleRenderer::new("typst").path(dir.path()).collect();
78
79 let expected = None;
80 assert_eq!(expected, actual);
81 dir.close()
82 }
83
84 #[test]
85 fn read_typst_present() -> io::Result<()> {
86 let dir = tempfile::tempdir()?;
87
88 File::create(dir.path().join("test.typ"))?.sync_all()?;
89
90 let actual = ModuleRenderer::new("typst").path(dir.path()).collect();
91 let expected = Some(format!(
92 "via {}",
93 Color::Rgb(0, 147, 167).bold().paint("t v0.10 ")
94 ));
95 assert_eq!(expected, actual);
96 dir.close()
97 }
98}