tfc_toolset_extras/
lib.rs

1pub mod error;
2pub mod file;
3
4pub use error::ExtrasError;
5pub use file::{
6    tag::TagsFile, variable::VariablesFile, workspace::WorkspacesFile,
7};
8use std::path::PathBuf;
9
10use http_cache_surf::{
11    CACacheManager, Cache, CacheMode, CacheOptions, HttpCache, HttpCacheOptions,
12};
13use regex::Regex;
14use surf::Client;
15use surf_governor::GovernorMiddleware;
16use surf_retry::{ExponentialBackoff, RetryMiddleware};
17use tfc_toolset::error::ToolError;
18
19pub fn build_governor() -> Result<GovernorMiddleware, ToolError> {
20    match GovernorMiddleware::per_second(30) {
21        Ok(g) => Ok(g),
22        Err(e) => Err(ToolError::General(e.into_inner())),
23    }
24}
25
26pub fn build_retry() -> RetryMiddleware<ExponentialBackoff> {
27    RetryMiddleware::new(
28        99,
29        ExponentialBackoff::builder().build_with_max_retries(10),
30        1,
31    )
32}
33
34pub fn build_cache_options() -> HttpCacheOptions {
35    HttpCacheOptions {
36        cache_options: Some(CacheOptions {
37            shared: false,
38            cache_heuristic: 0.0,
39            immutable_min_time_to_live: Default::default(),
40            ignore_cargo_cult: false,
41        }),
42        cache_key: None,
43        cache_mode_fn: None,
44        cache_bust: None,
45    }
46}
47
48pub fn default_client(path: Option<PathBuf>) -> Result<Client, ToolError> {
49    // Build the http client with a cache, governor, and retry enabled
50    Ok(Client::new().with(build_retry()).with(build_governor()?).with(Cache(
51        HttpCache {
52            mode: CacheMode::Default,
53            manager: CACacheManager {
54                path: path.unwrap_or_else(|| {
55                    dirs::cache_dir().unwrap_or("./".into()).join("tfc-toolset")
56                }),
57            },
58            options: build_cache_options(),
59        },
60    )))
61}
62
63pub fn parse_workspace_name(
64    workspace_name: &str,
65) -> Result<String, ExtrasError> {
66    let re = Regex::new("^[a-zA-Z0-9_-]*$")?;
67    let caps = re.captures(workspace_name);
68    match caps {
69        Some(_) => Ok(workspace_name.to_string()),
70        None => Err(ExtrasError::BadWorkspaceName(workspace_name.to_string())),
71    }
72}
73
74pub fn parse_tag_name(tag_name: &str) -> Result<String, ExtrasError> {
75    let re = Regex::new("^[a-zA-Z0-9_:-]*$")?;
76    let caps = re.captures(tag_name);
77    match caps {
78        Some(_) => Ok(tag_name.to_string()),
79        None => Err(ExtrasError::BadTagName(tag_name.to_string())),
80    }
81}