patchy/
utils.rs

1use anyhow::anyhow;
2use rand::{distributions, Rng as _};
3use reqwest::{header::USER_AGENT, Client};
4
5pub fn with_uuid(s: &str) -> String {
6    format!(
7        "{uuid}-{s}",
8        uuid = rand::thread_rng()
9            .sample_iter(&distributions::Alphanumeric)
10            .take(4)
11            .map(char::from)
12            .collect::<String>()
13    )
14}
15
16/// Converts a commit message to only contain lowercase characters, underscores and dashes
17pub fn normalize_commit_msg(commit_msg: &str) -> String {
18    commit_msg
19        .chars()
20        .map(|c| {
21            if c.is_alphanumeric() {
22                c.to_ascii_lowercase()
23            } else if c.is_whitespace() {
24                '_'
25            } else {
26                '-'
27            }
28        })
29        .collect()
30}
31
32pub fn display_link(text: &str, url: &str) -> String {
33    format!("\u{1b}]8;;{}\u{1b}\\{}\u{1b}]8;;\u{1b}\\", url, text)
34}
35
36pub async fn make_request(client: &Client, url: &str) -> anyhow::Result<String> {
37    let request = client
38        .get(url)
39        .header(USER_AGENT, "{APP_NAME}")
40        .send()
41        .await;
42
43    match request {
44        Ok(res) if res.status().is_success() => {
45            let out = res.text().await?;
46
47            Ok(out)
48        }
49        Ok(res) => {
50            let status = res.status();
51            let text = res.text().await?;
52
53            Err(anyhow!(
54                "Request failed with status: \
55                {status}\nRequested URL: {url}\nResponse: {text}",
56            ))
57        }
58        Err(err) => Err(anyhow!("Error sending request: {err}")),
59    }
60}
61
62#[macro_export]
63macro_rules! success {
64    ($($arg:tt)*) => {{
65        println!("{}{}{}",
66            $crate::INDENT,
67            colored::Colorize::bold(colored::Colorize::bright_green("✓ ")),
68            format!($($arg)*))
69    }};
70}
71
72#[macro_export]
73macro_rules! fail {
74    ($($arg:tt)*) => {{
75        eprintln!("{}{}{}",
76            $crate::INDENT,
77            colored::Colorize::bold(colored::Colorize::bright_red("✗ ")),
78            format!($($arg)*))
79    }};
80}
81
82#[macro_export]
83macro_rules! trace {
84    ($($arg:tt)*) => {{
85        if *$crate::flags::IS_VERBOSE {
86            eprintln!("{}{}{}",
87                $crate::INDENT,
88                colored::Colorize::bold(colored::Colorize::bright_yellow("--verbose: ")),
89                format!($($arg)*))
90        }
91    }};
92}
93
94#[macro_export]
95macro_rules! info {
96    ($($arg:tt)*) => {{
97        eprintln!("{}{}{}",
98            $crate::INDENT,
99            colored::Colorize::bright_blue(colored::Colorize::bold("i ")),
100            format!($($arg)*))
101    }};
102}
103
104/// Interact with the user to get a yes or a no answer
105#[macro_export]
106macro_rules! confirm_prompt {
107    ($($arg:tt)*) => {{
108        dialoguer::Confirm::new()
109            .with_prompt(format!(
110                "\n{INDENT}{} {}",
111                "»".bright_black(),
112                format!($($arg)*)
113            ))
114            .interact()
115            .unwrap()
116    }};
117}