ui_cli/shared/
rust_ui_client.rs

1use crate::shared::cli_error::{CliError, CliResult};
2use crate::shared::markdown_utils::extract_rust_code_from_markdown;
3
4pub struct RustUIClient;
5
6impl RustUIClient {
7    const BASE_URL: &str = "https://www.rust-ui.com/registry";
8
9    // URL builders - centralized URL construction
10    fn tree_url() -> String {
11        format!("{}/tree.md", Self::BASE_URL)
12    }
13
14    fn component_url(component_name: &str) -> String {
15        format!("{}/styles/default/{component_name}.md", Self::BASE_URL)
16    }
17
18    pub fn styles_index_url() -> String {
19        format!("{}/styles/index.json", Self::BASE_URL)
20    }
21
22    // Consolidated HTTP fetch method
23    async fn fetch_response(url: &str) -> CliResult<reqwest::Response> {
24        let response = reqwest::get(url).await.map_err(|_| CliError::registry_request_failed())?;
25
26        if !response.status().is_success() {
27            return Err(CliError::registry_request_failed());
28        }
29
30        Ok(response)
31    }
32
33    // Public API methods
34    pub async fn fetch_tree_md() -> CliResult<String> {
35        let response = Self::fetch_response(&Self::tree_url()).await?;
36        let content = response.text().await.map_err(|_| CliError::registry_request_failed())?;
37
38        if content.is_empty() {
39            return Err(CliError::registry_request_failed());
40        }
41
42        Ok(content)
43    }
44
45    pub async fn fetch_styles_default(component_name: &str) -> CliResult<String> {
46        let response = Self::fetch_response(&Self::component_url(component_name)).await?;
47        let markdown_content = response.text().await.map_err(|_| CliError::registry_request_failed())?;
48
49        extract_rust_code_from_markdown(&markdown_content).ok_or_else(CliError::registry_component_missing)
50    }
51
52    pub async fn fetch_styles_index() -> CliResult<String> {
53        let response = Self::fetch_response(&Self::styles_index_url()).await?;
54        let json =
55            response.json::<serde_json::Value>().await.map_err(|_| CliError::registry_invalid_format())?;
56
57        serde_json::to_string_pretty(&json)
58            .map_err(|err| CliError::malformed_registry(&format!("Failed to convert to pretty JSON: {err}")))
59    }
60}