Skip to main content

dsc/api/
themes.rs

1use anyhow::{Context, Result, anyhow};
2use serde_json::{Value, json};
3
4use super::client::DiscourseClient;
5use super::error::http_error;
6
7impl DiscourseClient {
8    /// List installed themes on the Discourse instance.
9    pub fn list_themes(&self) -> Result<Value> {
10        let response = self.get("/admin/themes.json")?;
11        let status = response.status();
12        let text = response.text().context("reading themes response body")?;
13        if !status.is_success() {
14            return Err(http_error("themes request", status, &text));
15        }
16        let value: Value = serde_json::from_str(&text).context("parsing themes response")?;
17        Ok(value)
18    }
19
20    /// Fetch a single theme by ID.
21    pub fn fetch_theme(&self, theme_id: u64) -> Result<Value> {
22        let response = self.get(&format!("/admin/themes/{}.json", theme_id))?;
23        let status = response.status();
24        let text = response.text().context("reading theme response body")?;
25        if !status.is_success() {
26            return Err(http_error("theme request", status, &text));
27        }
28        let value: Value = serde_json::from_str(&text).context("parsing theme response")?;
29        Ok(value)
30    }
31
32    /// Create a new theme and return its ID.
33    pub fn create_theme(&self, theme: &Value) -> Result<u64> {
34        let payload = json!({ "theme": theme });
35        let response = self
36            .post("/admin/themes.json")?
37            .json(&payload)
38            .send()
39            .context("creating theme")?;
40        let status = response.status();
41        let text = response.text().context("reading create theme response")?;
42        if !status.is_success() {
43            return Err(http_error("create theme request", status, &text));
44        }
45        let value: Value =
46            serde_json::from_str(&text).context("parsing create theme response")?;
47        let id = value
48            .get("theme")
49            .and_then(|v| v.get("id"))
50            .or_else(|| value.get("id"))
51            .and_then(|v| v.as_u64())
52            .ok_or_else(|| anyhow!("missing theme id in create response"))?;
53        Ok(id)
54    }
55
56    /// Delete a theme by ID.
57    pub fn delete_theme(&self, theme_id: u64) -> Result<()> {
58        let response = self.delete(&format!("/admin/themes/{}.json", theme_id))?;
59        let status = response.status();
60        let text = response.text().context("reading delete theme response")?;
61        if !status.is_success() {
62            return Err(http_error("delete theme request", status, &text));
63        }
64        Ok(())
65    }
66
67    /// Update an existing theme.
68    pub fn update_theme(&self, theme_id: u64, theme: &Value) -> Result<()> {
69        let payload = json!({ "theme": theme });
70        let response = self
71            .put(&format!("/admin/themes/{}.json", theme_id))?
72            .json(&payload)
73            .send()
74            .context("updating theme")?;
75        let status = response.status();
76        let text = response.text().context("reading update theme response")?;
77        if !status.is_success() {
78            return Err(http_error("update theme request", status, &text));
79        }
80        Ok(())
81    }
82}