Skip to main content

contract_cli/
typst_assets.rs

1// Embed contract templates + shared helpers. Extract on first use into the
2// shared accounting-suite assets dir, namespaced under `contracts/`.
3
4use rust_embed::RustEmbed;
5
6use crate::config;
7use crate::error::Result;
8
9#[derive(RustEmbed)]
10#[folder = "typst/"]
11#[prefix = ""]
12pub struct Assets;
13
14fn root() -> Result<std::path::PathBuf> {
15    Ok(config::assets_path()?.join("contracts"))
16}
17
18pub fn ensure_extracted() -> Result<()> {
19    let root = root()?;
20    std::fs::create_dir_all(&root)?;
21    for path in Assets::iter() {
22        let file = Assets::get(&path).expect("embedded asset");
23        let dest = root.join(path.as_ref());
24        if let Some(parent) = dest.parent() {
25            std::fs::create_dir_all(parent)?;
26        }
27        let needs_write = match std::fs::read(&dest) {
28            Ok(existing) => existing != file.data.as_ref(),
29            Err(_) => true,
30        };
31        if needs_write {
32            std::fs::write(&dest, file.data.as_ref())?;
33        }
34    }
35    Ok(())
36}
37
38pub fn template_dir() -> Result<std::path::PathBuf> {
39    Ok(root()?.join("templates"))
40}
41
42pub fn template_path(name: &str) -> Result<std::path::PathBuf> {
43    Ok(template_dir()?.join(format!("{name}.typ")))
44}
45
46pub fn list_templates() -> Result<Vec<String>> {
47    let dir = template_dir()?;
48    let mut names = Vec::new();
49    if dir.exists() {
50        for entry in std::fs::read_dir(&dir)? {
51            let entry = entry?;
52            let path = entry.path();
53            if path.extension().and_then(|s| s.to_str()) == Some("typ") {
54                if let Some(name) = path.file_stem().and_then(|s| s.to_str()) {
55                    names.push(name.to_string());
56                }
57            }
58        }
59    }
60    names.sort();
61    Ok(names)
62}
63
64pub fn has_template(name: &str) -> Result<bool> {
65    Ok(template_path(name)?.exists())
66}
67
68pub fn project_root() -> Result<std::path::PathBuf> {
69    root()
70}