Skip to main content

podbox/
profiles.rs

1use std::path::PathBuf;
2
3/// A named, ready-to-use configuration template.
4pub struct Profile {
5    pub name: String,
6    pub label: String,
7    pub description: String,
8    pub toml: String,
9}
10
11/// List all available profiles (bundled + user-defined).
12pub fn all() -> Vec<Profile> {
13    let mut profiles = vec![cachy(), fedora(), ubuntu(), dev()];
14    profiles.extend(user_profiles());
15    profiles
16}
17
18/// Find a profile by name (case-insensitive).
19pub fn find(name: &str) -> Option<Profile> {
20    let lower = name.to_lowercase();
21    // Check bundled first, then user-defined
22    for p in [cachy(), fedora(), ubuntu(), dev()] {
23        if p.name == lower {
24            return Some(p);
25        }
26    }
27    user_profiles().into_iter().find(|p| p.name == lower)
28}
29
30fn user_profiles_dir() -> PathBuf {
31    crate::config::config_dir().join("profiles")
32}
33
34fn user_profiles() -> Vec<Profile> {
35    let dir = user_profiles_dir();
36    if !dir.is_dir() {
37        return vec![];
38    }
39    let mut profiles = Vec::new();
40    if let Ok(entries) = std::fs::read_dir(&dir) {
41        for entry in entries.flatten() {
42            let path = entry.path();
43            if path.extension().map(|e| e == "toml").unwrap_or(false) {
44                if let Ok(content) = std::fs::read_to_string(&path) {
45                    let name = path
46                        .file_stem()
47                        .map(|s| s.to_string_lossy().to_lowercase())
48                        .unwrap_or_default();
49                    profiles.push(Profile {
50                        label: name.clone(),
51                        description: format!("User-defined profile ({})", name),
52                        toml: content,
53                        name,
54                    });
55                }
56            }
57        }
58    }
59    profiles
60}
61
62fn cachy() -> Profile {
63    Profile {
64        name: "cachy".into(),
65        label: "CachyOS".into(),
66        description: "CachyOS-based environment optimized for gaming".into(),
67        toml: include_str!("profiles/cachy.toml").into(),
68    }
69}
70
71fn fedora() -> Profile {
72    Profile {
73        name: "fedora".into(),
74        label: "Fedora".into(),
75        description: "Fedora-based general-purpose environment".into(),
76        toml: include_str!("profiles/fedora.toml").into(),
77    }
78}
79
80fn ubuntu() -> Profile {
81    Profile {
82        name: "ubuntu".into(),
83        label: "Ubuntu".into(),
84        description: "Ubuntu-based general-purpose environment".into(),
85        toml: include_str!("profiles/ubuntu.toml").into(),
86    }
87}
88
89fn dev() -> Profile {
90    Profile {
91        name: "dev".into(),
92        label: "Dev".into(),
93        description: "CachyOS-based development environment with mise, neovim, git, and dev tooling pre-installed".into(),
94        toml: include_str!("profiles/dev.toml").into(),
95    }
96}
97
98/// List profile names for tab completion / CLI hints.
99pub fn list_names() -> Vec<String> {
100    all().into_iter().map(|p| p.name).collect()
101}