1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use toml::Table;
4
5use crate::prompt_store::PromptBackendType;
6use crate::utils::{get_string_hashmap_from_value, get_vec_string_from_value, is_empty_table};
7
8#[derive(Debug, Clone, Default, Serialize, Deserialize)]
9pub struct Profile {
10 #[serde(skip)]
11 pub name: String,
12 #[serde(skip_serializing_if = "is_empty_table")]
13 pub variables: Table,
14 pub dependencies: Vec<String>,
15 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
16 pub prompts: HashMap<String, String>,
17 #[serde(default, skip_serializing_if = "Option::is_none")]
20 pub prompt_backend: Option<PromptBackendType>,
21 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub bitwarden_note: Option<String>,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
25 pub platform: Option<String>,
26}
27
28impl Profile {
29 pub fn new(name: &str) -> Self {
30 Profile {
31 name: name.to_string(),
32 ..Default::default()
33 }
34 }
35
36 pub fn from_table(name: &str, table: &Table) -> anyhow::Result<Self> {
37 let variables = match table.get("variables") {
38 Some(var_block) => var_block
39 .as_table()
40 .ok_or_else(|| anyhow::anyhow!("The 'variables' field must be a table"))?
41 .clone(),
42 None => Table::new(),
43 };
44 let dependencies = get_vec_string_from_value(table.get("dependencies"))?;
45 let prompts = get_string_hashmap_from_value(table.get("prompts"))?;
46 let prompt_backend = table
47 .get("prompt_backend")
48 .and_then(|v| v.as_str())
49 .map(PromptBackendType::parse)
50 .transpose()?;
51 let bitwarden_note = table
52 .get("bitwarden_note")
53 .and_then(|v| v.as_str())
54 .map(|s| s.to_string());
55 let platform = table
56 .get("platform")
57 .and_then(|v| v.as_str())
58 .map(|s| s.to_string());
59 Ok(Self {
60 name: name.to_string(),
61 variables,
62 dependencies,
63 prompts,
64 prompt_backend,
65 bitwarden_note,
66 platform,
67 })
68 }
69}