use client_application::conversions::{ wire_to_display_hint, wire_to_layout, wire_to_value, wire_to_widget_state, }; use domain::{ AlignItems, ContainerNode, Direction, DisplayHint, DisplayHintKind, JustifyContent, LayoutChild, LayoutNode, Sizing, Value, WidgetError, WidgetState, }; use protocol::{ WireContainerNode, WireDirection, WireDisplayHint, WireKeyValue, WireLayoutChild, WireLayoutNode, WireSizing, WireValue, WireWidgetError, WireWidgetState, }; use std::collections::BTreeMap; fn value_to_wire(v: &Value) -> WireValue { match v { Value::Null => WireValue::Null, Value::Bool(b) => WireValue::Bool(*b), Value::Number(n) => WireValue::Number(*n), Value::String(s) => WireValue::String(s.clone()), Value::Array(arr) => WireValue::Array(arr.iter().map(value_to_wire).collect()), Value::Object(map) => WireValue::Object( map.iter() .map(|(k, v)| (k.clone(), value_to_wire(v))) .collect(), ), } } #[test] fn value_converts_to_wire_and_back() { let original = Value::Object(BTreeMap::from([( "items".into(), Value::Array(vec![ Value::String("hello".into()), Value::Number(42.0), Value::Bool(true), Value::Null, ]), )])); let wire = value_to_wire(&original); let roundtripped = wire_to_value(wire); assert_eq!(original, roundtripped); } #[test] fn widget_state_with_error_converts_to_wire_and_back() { let original = WidgetState { data: BTreeMap::from([("temp".into(), Value::Number(5.4))]), error: Some(WidgetError::SourceUnavailable), }; let wire = WireWidgetState { data: original .data .iter() .map(|(k, v)| WireKeyValue { key: k.clone(), value: value_to_wire(v), }) .collect(), error: Some(WireWidgetError::SourceUnavailable), }; let roundtripped = wire_to_widget_state(wire); assert_eq!(original, roundtripped); } #[test] fn layout_tree_converts_to_wire_and_back() { let original = LayoutNode::Container(ContainerNode { direction: Direction::Row, gap: 4, padding: 2, justify_content: JustifyContent::Start, align_items: AlignItems::Stretch, children: vec![ LayoutChild { sizing: Sizing::Flex(1), node: LayoutNode::Leaf(1), }, LayoutChild { sizing: Sizing::Fixed(100), node: LayoutNode::Container(ContainerNode { direction: Direction::Column, gap: 2, padding: 0, justify_content: JustifyContent::Start, align_items: AlignItems::Stretch, children: vec![LayoutChild { sizing: Sizing::Flex(1), node: LayoutNode::Leaf(2), }], }), }, ], }); let wire = WireLayoutNode::Container(WireContainerNode { direction: WireDirection::Row, gap: 4, padding: 2, justify_content: protocol::WireJustifyContent::Start, align_items: protocol::WireAlignItems::Stretch, children: vec![ WireLayoutChild { sizing: WireSizing::Flex(1), node: WireLayoutNode::Leaf(1), }, WireLayoutChild { sizing: WireSizing::Fixed(100), node: WireLayoutNode::Container(WireContainerNode { direction: WireDirection::Column, gap: 2, padding: 0, justify_content: protocol::WireJustifyContent::Start, align_items: protocol::WireAlignItems::Stretch, children: vec![WireLayoutChild { sizing: WireSizing::Flex(1), node: WireLayoutNode::Leaf(2), }], }), }, ], }); let roundtripped = wire_to_layout(wire); assert_eq!(original, roundtripped); } #[test] fn display_hint_converts_to_wire_and_back() { for (hint, wire_kind) in [ ( DisplayHintKind::IconValue, protocol::WireDisplayHintKind::IconValue, ), ( DisplayHintKind::TextBlock, protocol::WireDisplayHintKind::TextBlock, ), ( DisplayHintKind::KeyValue, protocol::WireDisplayHintKind::KeyValue, ), ] { let original = DisplayHint::new(hint); let wire = WireDisplayHint::new(wire_kind); let roundtripped = wire_to_display_hint(wire); assert_eq!(original, roundtripped); } }