Skip to main content

horto_os_ui_shared/
embed.rs

1//! Embedded `assets/` tree (config templates and `docker_source`) via `rust-embed`.
2
3use rust_embed::Embed;
4use std::borrow::Cow;
5
6/// Embedded setup templates and docker source tree.
7#[derive(Embed)]
8#[folder = "../../assets/"]
9pub struct Assets;
10
11/// Return embedded file bytes for `path`, if present.
12#[must_use]
13pub fn get(path: &str) -> Option<Cow<'static, [u8]>> {
14    Assets::get(path).map(|f| f.data)
15}
16
17/// Return embedded file as UTF-8 string for `path`, if present and valid UTF-8.
18#[must_use]
19pub fn get_str(path: &str) -> Option<String> {
20    get(path).and_then(|d| String::from_utf8(d.into_owned()).ok())
21}
22
23/// List files under an embedded prefix (e.g. `config/` or `docker_source/`).
24#[must_use]
25pub fn list_prefix(prefix: &str) -> Vec<String> {
26    Assets::iter()
27        .filter(|p| p.starts_with(prefix))
28        .map(|p| p.to_string())
29        .collect()
30}
31
32/// Top-level entries under `config/` (file or directory names as in the embed).
33#[must_use]
34pub fn config_top_entries() -> Vec<String> {
35    let mut names = std::collections::BTreeSet::new();
36    for path in Assets::iter() {
37        let Some(rest) = path.strip_prefix("config/") else {
38            continue;
39        };
40        let name = rest.split('/').next().unwrap_or(rest);
41        if !name.is_empty() {
42            names.insert(name.to_string());
43        }
44    }
45    names.into_iter().collect()
46}