ratatui_toolkit/services/theme/loader/theme_json.rs
1//! JSON schema types for parsing opencode theme files.
2
3use std::collections::HashMap;
4
5use serde::{Deserialize, Serialize};
6
7/// Represents a color value in the theme JSON.
8///
9/// Color values can be:
10/// - A direct hex color string (e.g., `"#ff0000"`)
11/// - A reference to a definition (e.g., `"darkRed"`)
12/// - A variant object with dark/light values
13///
14/// # Examples
15///
16/// ```json
17/// // Direct hex
18/// "primary": "#ff0000"
19///
20/// // Reference to def
21/// "primary": "darkBlueBright"
22///
23/// // Variant object
24/// "primary": { "dark": "darkBlueBright", "light": "lightBlue" }
25/// ```
26#[derive(Debug, Clone, Deserialize, Serialize)]
27#[serde(untagged)]
28pub enum ColorValue {
29 /// A direct color string (hex or reference name).
30 Direct(String),
31
32 /// A variant object with dark and light values.
33 Variant {
34 /// Color value for dark mode (hex or reference).
35 dark: String,
36 /// Color value for light mode (hex or reference).
37 light: String,
38 },
39}
40
41/// Root structure of an opencode theme JSON file.
42///
43/// # Structure
44///
45/// ```json
46/// {
47/// "$schema": "https://opencode.ai/theme.json",
48/// "defs": {
49/// "colorName": "#hexcode"
50/// },
51/// "theme": {
52/// "semantic": { "dark": "colorName", "light": "colorName" }
53/// }
54/// }
55/// ```
56#[derive(Debug, Clone, Deserialize, Serialize)]
57pub struct ThemeJson {
58 /// JSON schema URL (optional, used for validation).
59 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
60 pub schema: Option<String>,
61
62 /// Named color definitions.
63 ///
64 /// Maps color names to hex color values. These are used for
65 /// references in the `theme` section.
66 #[serde(default)]
67 pub defs: HashMap<String, String>,
68
69 /// Semantic color mappings.
70 ///
71 /// Maps semantic color names (e.g., "primary", "error") to
72 /// color values, which can be direct hex codes, references
73 /// to `defs`, or variant objects.
74 #[serde(default)]
75 pub theme: HashMap<String, ColorValue>,
76}