1use serde::{Deserialize, Serialize};
2use std::collections::BTreeMap;
3
4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[serde(untagged)]
10pub enum PropValue {
11 String(String),
13
14 Number(f64),
16
17 Bool(bool),
19
20 Nil,
22
23 Color { r: f64, g: f64, b: f64, a: f64 },
25
26 ActionRef {
30 #[serde(rename = "__action")]
31 action: String,
32 #[serde(rename = "__args", skip_serializing_if = "Option::is_none")]
33 args: Option<Vec<PropValue>>,
34 },
35
36 Lambda {
39 #[serde(rename = "__lambda")]
40 lambda_id: u32,
41 },
42
43 List(Vec<PropValue>),
45
46 Record(BTreeMap<String, PropValue>),
48}
49
50impl PropValue {
53 pub fn action(name: impl Into<String>) -> Self {
55 PropValue::ActionRef {
56 action: name.into(),
57 args: None,
58 }
59 }
60
61 pub fn action_with_args(name: impl Into<String>, args: Vec<PropValue>) -> Self {
63 PropValue::ActionRef {
64 action: name.into(),
65 args: Some(args),
66 }
67 }
68
69 pub fn lambda(id: u32) -> Self {
71 PropValue::Lambda { lambda_id: id }
72 }
73
74 pub fn color(r: f64, g: f64, b: f64, a: f64) -> Self {
76 PropValue::Color { r, g, b, a }
77 }
78
79 pub fn type_name(&self) -> &'static str {
81 match self {
82 PropValue::String(_) => "string",
83 PropValue::Number(_) => "number",
84 PropValue::Bool(_) => "bool",
85 PropValue::Nil => "nil",
86 PropValue::Color { .. } => "color",
87 PropValue::ActionRef { .. } => "action",
88 PropValue::Lambda { .. } => "lambda",
89 PropValue::List(_) => "list",
90 PropValue::Record(_) => "record",
91 }
92 }
93}
94
95impl From<&str> for PropValue {
98 fn from(s: &str) -> Self {
99 PropValue::String(s.to_string())
100 }
101}
102
103impl From<String> for PropValue {
104 fn from(s: String) -> Self {
105 PropValue::String(s)
106 }
107}
108
109impl From<f64> for PropValue {
110 fn from(n: f64) -> Self {
111 PropValue::Number(n)
112 }
113}
114
115impl From<i64> for PropValue {
116 fn from(n: i64) -> Self {
117 PropValue::Number(n as f64)
118 }
119}
120
121impl From<bool> for PropValue {
122 fn from(b: bool) -> Self {
123 PropValue::Bool(b)
124 }
125}