Skip to main content

dsc/api/
palettes.rs

1use anyhow::{Context, Result, anyhow};
2use serde_json::Value;
3use std::collections::BTreeMap;
4
5use super::client::DiscourseClient;
6use super::error::http_error;
7
8impl DiscourseClient {
9    /// List color schemes (palettes) available on the Discourse instance.
10    pub fn list_color_schemes(&self) -> Result<Value> {
11        let response = self.get("/admin/color_schemes.json")?;
12        let status = response.status();
13        let text = response
14            .text()
15            .context("reading color schemes response body")?;
16        if !status.is_success() {
17            return Err(http_error("color schemes request", status, &text));
18        }
19        let value: Value = serde_json::from_str(&text).context("parsing color schemes response")?;
20        Ok(value)
21    }
22
23    /// Fetch a color scheme (palette) by ID.
24    pub fn fetch_color_scheme(&self, scheme_id: u64) -> Result<Value> {
25        let response = self.get(&format!("/admin/color_schemes/{}.json", scheme_id))?;
26        let status = response.status();
27        let text = response
28            .text()
29            .context("reading color scheme response body")?;
30        if !status.is_success() {
31            return Err(http_error("color scheme request", status, &text));
32        }
33        let value: Value = serde_json::from_str(&text).context("parsing color scheme response")?;
34        Ok(value)
35    }
36
37    /// Create a new color scheme (palette).
38    pub fn create_color_scheme(
39        &self,
40        name: &str,
41        colors: &BTreeMap<String, String>,
42    ) -> Result<u64> {
43        let mut payload: Vec<(String, String)> = Vec::new();
44        payload.push(("color_scheme[name]".to_string(), name.to_string()));
45        for (key, value) in colors {
46            payload.push((format!("color_scheme[colors][{}]", key), value.to_string()));
47        }
48        let response = self
49            .send_retrying(|| Ok(self.post("/admin/color_schemes.json")?.form(&payload)))?;
50        let status = response.status();
51        let text = response.text().context("reading color scheme response")?;
52        if !status.is_success() {
53            return Err(http_error("create color scheme request", status, &text));
54        }
55        let value: Value =
56            serde_json::from_str(&text).context("parsing create color scheme response")?;
57        let id = value
58            .get("color_scheme")
59            .and_then(|v| v.get("id"))
60            .or_else(|| value.get("id"))
61            .and_then(|v| v.as_u64())
62            .ok_or_else(|| anyhow!("missing color scheme id in response"))?;
63        Ok(id)
64    }
65
66    /// Update an existing color scheme (palette).
67    pub fn update_color_scheme(
68        &self,
69        scheme_id: u64,
70        name: Option<&str>,
71        colors: &BTreeMap<String, String>,
72    ) -> Result<()> {
73        let mut payload: Vec<(String, String)> = Vec::new();
74        if let Some(name) = name {
75            if !name.trim().is_empty() {
76                payload.push(("color_scheme[name]".to_string(), name.to_string()));
77            }
78        }
79        for (key, value) in colors {
80            payload.push((format!("color_scheme[colors][{}]", key), value.to_string()));
81        }
82        let path = format!("/admin/color_schemes/{}.json", scheme_id);
83        let response = self.send_retrying(|| Ok(self.put(&path)?.form(&payload)))?;
84        let status = response.status();
85        let text = response.text().context("reading color scheme response")?;
86        if !status.is_success() {
87            return Err(http_error("update color scheme request", status, &text));
88        }
89        Ok(())
90    }
91}