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            .post("/admin/color_schemes.json")?
50            .form(&payload)
51            .send()
52            .context("creating color scheme")?;
53        let status = response.status();
54        let text = response.text().context("reading color scheme response")?;
55        if !status.is_success() {
56            return Err(http_error("create color scheme request", status, &text));
57        }
58        let value: Value =
59            serde_json::from_str(&text).context("parsing create color scheme response")?;
60        let id = value
61            .get("color_scheme")
62            .and_then(|v| v.get("id"))
63            .or_else(|| value.get("id"))
64            .and_then(|v| v.as_u64())
65            .ok_or_else(|| anyhow!("missing color scheme id in response"))?;
66        Ok(id)
67    }
68
69    /// Update an existing color scheme (palette).
70    pub fn update_color_scheme(
71        &self,
72        scheme_id: u64,
73        name: Option<&str>,
74        colors: &BTreeMap<String, String>,
75    ) -> Result<()> {
76        let mut payload: Vec<(String, String)> = Vec::new();
77        if let Some(name) = name {
78            if !name.trim().is_empty() {
79                payload.push(("color_scheme[name]".to_string(), name.to_string()));
80            }
81        }
82        for (key, value) in colors {
83            payload.push((format!("color_scheme[colors][{}]", key), value.to_string()));
84        }
85        let response = self
86            .put(&format!("/admin/color_schemes/{}.json", scheme_id))?
87            .form(&payload)
88            .send()
89            .context("updating color scheme")?;
90        let status = response.status();
91        let text = response.text().context("reading color scheme response")?;
92        if !status.is_success() {
93            return Err(http_error("update color scheme request", status, &text));
94        }
95        Ok(())
96    }
97}