StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.
| 1 | use crate::types::Color; |
| 2 | |
| 3 | /// A node in the semantic UI tree. |
| 4 | /// This decouples the description of the UI from its runtime instantiation. |
| 5 | #[derive(Debug, Clone, PartialEq)] |
| 6 | pub enum UiNode { |
| 7 | /// A widget with a name, properties, and children. |
| 8 | Widget(WidgetNode), |
| 9 | /// A text node. |
| 10 | Text(String), |
| 11 | /// A container for multiple nodes. |
| 12 | Fragment(Vec<UiNode>), |
| 13 | } |
| 14 | |
| 15 | /// Description of a widget. |
| 16 | #[derive(Debug, Clone, PartialEq)] |
| 17 | pub struct WidgetNode { |
| 18 | /// The name of the widget (e.g., "Container", "Button"). |
| 19 | pub name: String, |
| 20 | /// Properties configuration. |
| 21 | pub props: Vec<(String, PropValue)>, |
| 22 | /// Child nodes. |
| 23 | pub children: Vec<UiNode>, |
| 24 | } |
| 25 | |
| 26 | /// Value of a property. |
| 27 | /// Note: `Any` is restricted to callbacks and runtime handles. |
| 28 | #[derive(Debug)] |
| 29 | pub enum PropValue { |
| 30 | String(String), |
| 31 | Int(i64), |
| 32 | Float(f64), |
| 33 | Bool(bool), |
| 34 | Color(Color), |
| 35 | // Callbacks or IDs can be added here explicitly, e.g. Callback(usize) |
| 36 | } |
| 37 | |
| 38 | impl PartialEq for PropValue { |
| 39 | fn eq(&self, other: &Self) -> bool { |
| 40 | match (self, other) { |
| 41 | (PropValue::String(a), PropValue::String(b)) => a == b, |
| 42 | (PropValue::Int(a), PropValue::Int(b)) => a == b, |
| 43 | (PropValue::Float(a), PropValue::Float(b)) => a == b, |
| 44 | (PropValue::Bool(a), PropValue::Bool(b)) => a == b, |
| 45 | (PropValue::Color(a), PropValue::Color(b)) => a == b, |
| 46 | _ => false, |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | impl Clone for PropValue { |
| 52 | fn clone(&self) -> Self { |
| 53 | match self { |
| 54 | PropValue::String(s) => PropValue::String(s.clone()), |
| 55 | PropValue::Int(i) => PropValue::Int(*i), |
| 56 | PropValue::Float(f) => PropValue::Float(*f), |
| 57 | PropValue::Bool(b) => PropValue::Bool(*b), |
| 58 | PropValue::Color(c) => PropValue::Color(*c), |
| 59 | } |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | // Helpers for manual construction if needed (though macro handles this) |
| 64 | impl UiNode { |
| 65 | pub fn widget(name: impl Into<String>) -> Self { |
| 66 | UiNode::Widget(WidgetNode { |
| 67 | name: name.into(), |
| 68 | props: Vec::new(), |
| 69 | children: Vec::new(), |
| 70 | }) |
| 71 | } |
| 72 | |
| 73 | pub fn text(text: impl Into<String>) -> Self { |
| 74 | UiNode::Text(text.into()) |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | impl WidgetNode { |
| 79 | pub fn prop(mut self, name: impl Into<String>, value: PropValue) -> Self { |
| 80 | self.props.push((name.into(), value)); |
| 81 | self |
| 82 | } |
| 83 | |
| 84 | pub fn child(mut self, node: UiNode) -> Self { |
| 85 | self.children.push(node); |
| 86 | self |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | // Initial `From` implementations for easy conversion in macro generation |
| 91 | impl From<String> for PropValue { |
| 92 | fn from(v: String) -> Self { |
| 93 | PropValue::String(v) |
| 94 | } |
| 95 | } |
| 96 | impl From<&str> for PropValue { |
| 97 | fn from(v: &str) -> Self { |
| 98 | PropValue::String(v.to_string()) |
| 99 | } |
| 100 | } |
| 101 | impl From<i64> for PropValue { |
| 102 | fn from(v: i64) -> Self { |
| 103 | PropValue::Int(v) |
| 104 | } |
| 105 | } |
| 106 | impl From<i32> for PropValue { |
| 107 | fn from(v: i32) -> Self { |
| 108 | PropValue::Int(v as i64) |
| 109 | } |
| 110 | } |
| 111 | impl From<f64> for PropValue { |
| 112 | fn from(v: f64) -> Self { |
| 113 | PropValue::Float(v) |
| 114 | } |
| 115 | } |
| 116 | impl From<f32> for PropValue { |
| 117 | fn from(v: f32) -> Self { |
| 118 | PropValue::Float(v as f64) |
| 119 | } |
| 120 | } |
| 121 | impl From<bool> for PropValue { |
| 122 | fn from(v: bool) -> Self { |
| 123 | PropValue::Bool(v) |
| 124 | } |
| 125 | } |
| 126 | impl From<Color> for PropValue { |
| 127 | fn from(v: Color) -> Self { |
| 128 | PropValue::Color(v) |
| 129 | } |
| 130 | } |
| 131 |