use std::env;
use std::path::PathBuf;
use crate::Result;
const VAR_PREFERENCES: &str = "alfred_preferences";
const VAR_PREFERENCES_LOCALHASH: &str = "alfred_preferences_localhash";
const VAR_THEME: &str = "alfred_theme";
const VAR_THEME_BACKGROUND: &str = "alfred_theme_background";
const VAR_THEME_SELECTION_BACKGROUND: &str = "alfred_theme_selection_background";
const VAR_THEME_SUBTEXT: &str = "alfred_theme_subtext";
const VAR_VERSION: &str = "alfred_version";
const VAR_VERSION_BUILD: &str = "alfred_version_build";
const VAR_WORKFLOW_BUNDLEID: &str = "alfred_workflow_bundleid";
const VAR_WORKFLOW_CACHE: &str = "alfred_workflow_cache";
const VAR_WORKFLOW_DATA: &str = "alfred_workflow_data";
const VAR_WORKFLOW_NAME: &str = "alfred_workflow_name";
const VAR_WORKFLOW_DESCRIPTION: &str = "alfred_workflow_description";
const VAR_WORKFLOW_UID: &str = "alfred_workflow_uid";
const VAR_WORKFLOW_VERSION: &str = "alfred_workflow_version";
const VAR_WORKFLOW_KEYWORD: &str = "alfred_workflow_keyword";
const VAR_DEBUG: &str = "alfred_debug";
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct WorkflowConfig {
pub workflow_bundleid: String,
pub workflow_cache: PathBuf,
pub workflow_data: PathBuf,
pub version: String,
pub version_build: String,
pub workflow_name: String,
pub workflow_version: Option<String>,
pub preferences: Option<String>,
pub preferences_localhash: Option<String>,
pub theme: Option<String>,
pub theme_background: Option<String>,
pub theme_selection_background: Option<String>,
pub theme_subtext: Option<String>,
pub workflow_description: Option<String>,
pub workflow_uid: Option<String>,
pub workflow_keyword: Option<String>,
pub debug: bool,
}
pub trait ConfigProvider {
fn config(&self) -> Result<WorkflowConfig>;
}
pub struct AlfredEnvProvider;
impl ConfigProvider for AlfredEnvProvider {
fn config(&self) -> Result<WorkflowConfig> {
let debug = env::var(VAR_DEBUG).unwrap_or_default();
let debug = debug == "1" || debug.to_lowercase() == "true";
let config = WorkflowConfig {
workflow_bundleid: env::var(VAR_WORKFLOW_BUNDLEID).map_err(|_| {
format!("Missing required environment variable: {VAR_WORKFLOW_BUNDLEID}")
})?,
workflow_cache: env::var(VAR_WORKFLOW_CACHE)
.map_err(|_| {
format!("Missing required environment variable: {VAR_WORKFLOW_CACHE}")
})?
.into(),
workflow_data: env::var(VAR_WORKFLOW_DATA)
.map_err(|_| format!("Missing required environment variable: {VAR_WORKFLOW_DATA}"))?
.into(),
version: env::var(VAR_VERSION)
.map_err(|_| format!("Missing required environment variable: {VAR_VERSION}"))?,
version_build: env::var(VAR_VERSION_BUILD).map_err(|_| {
format!("Missing required environment variable: {VAR_VERSION_BUILD}")
})?,
workflow_name: env::var(VAR_WORKFLOW_NAME).map_err(|_| {
format!("Missing required environment variable: {VAR_WORKFLOW_NAME}")
})?,
workflow_version: env::var(VAR_WORKFLOW_VERSION).ok(),
preferences: env::var(VAR_PREFERENCES).ok(),
preferences_localhash: env::var(VAR_PREFERENCES_LOCALHASH).ok(),
theme: env::var(VAR_THEME).ok(),
theme_background: env::var(VAR_THEME_BACKGROUND).ok(),
theme_selection_background: env::var(VAR_THEME_SELECTION_BACKGROUND).ok(),
theme_subtext: env::var(VAR_THEME_SUBTEXT).ok(),
workflow_description: env::var(VAR_WORKFLOW_DESCRIPTION).ok(),
workflow_uid: env::var(VAR_WORKFLOW_UID).ok(),
workflow_keyword: env::var(VAR_WORKFLOW_KEYWORD).ok(),
debug,
};
Ok(config)
}
}
pub struct TestingProvider(pub PathBuf);
impl ConfigProvider for TestingProvider {
fn config(&self) -> Result<WorkflowConfig> {
Ok(WorkflowConfig {
preferences: Some("/Users/Crayons/Dropbox/Alfred/Alfred.alfredpreferences".to_string()),
preferences_localhash: Some("adbd4f66bc3ae8493832af61a41ee609b20d8705".to_string()),
theme: Some("alfred.theme.yosemite".to_string()),
theme_background: Some("rgba(255,255,255,0.98)".to_string()),
theme_selection_background: Some("rgba(255,255,255,0.98)".to_string()),
theme_subtext: Some("3".to_string()),
version: "5.0".to_string(),
version_build: "2058".to_string(),
workflow_bundleid: "com.alfredapp.googlesuggest".to_string(),
workflow_cache: self.0.join("workflow_cache"),
workflow_data: self.0.join("workflow_data"),
workflow_name: "Test Workflow".to_string(),
workflow_description: Some(
"The description of the workflow we use for testing".to_string(),
),
workflow_version: Some("1.7".to_string()),
workflow_uid: Some("user.workflow.B0AC54EC-601C-479A-9428-01F9FD732959".to_string()),
workflow_keyword: None,
debug: true,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_alfred_env_provider_with_errors() {
temp_env::with_vars(
[
(VAR_DEBUG, Some("true")),
(VAR_WORKFLOW_CACHE, None),
(VAR_WORKFLOW_DATA, None),
],
|| {
let provider = AlfredEnvProvider;
let result = provider.config();
assert!(result.is_err(), "{result:?}");
},
);
}
#[test]
fn test_alfred_env_provider_with_required_envvars() {
temp_env::with_vars(
[
(VAR_WORKFLOW_CACHE, Some("/made/up/cache_dir")),
(VAR_WORKFLOW_DATA, Some("/made/up/data_dir")),
(VAR_WORKFLOW_BUNDLEID, Some("com.alfredapp.googlesuggest")),
(VAR_VERSION, Some("5.0")),
(VAR_VERSION_BUILD, Some("2058")),
(VAR_WORKFLOW_NAME, Some("Test Workflow")),
(VAR_WORKFLOW_VERSION, Some("1.7")),
(VAR_DEBUG, Some("true")),
],
|| {
let provider = AlfredEnvProvider;
let result = provider.config();
assert!(result.is_ok(), "{result:?}");
},
);
}
#[test]
fn test_testing_provider() {
let dir = tempfile::tempdir().unwrap().keep();
let provider = TestingProvider(dir);
let config = provider.config().unwrap();
assert_eq!(config.workflow_bundleid, "com.alfredapp.googlesuggest");
assert_eq!(config.workflow_name, "Test Workflow");
assert_eq!(config.version, "5.0");
assert_eq!(config.version_build, "2058");
}
}