node.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. use crate::{state::State, tree::NodeId};
  2. use dioxus_core::{AnyValue, BorrowedAttributeValue, ElementId};
  3. use rustc_hash::{FxHashMap, FxHashSet};
  4. use std::fmt::Debug;
  5. /// The node is stored client side and stores only basic data about the node.
  6. #[derive(Debug, Clone)]
  7. pub struct Node<S: State, V: FromAnyValue = ()> {
  8. /// The transformed state of the node.
  9. pub state: S,
  10. /// The raw data for the node
  11. pub node_data: NodeData<V>,
  12. }
  13. #[derive(Debug, Clone)]
  14. pub struct NodeData<V: FromAnyValue = ()> {
  15. /// The id of the node
  16. pub node_id: NodeId,
  17. /// The id of the node in the vdom.
  18. pub element_id: Option<ElementId>,
  19. /// Additional inforation specific to the node type
  20. pub node_type: NodeType<V>,
  21. }
  22. /// A type of node with data specific to the node type. The types are a subset of the [VNode] types.
  23. #[derive(Debug, Clone)]
  24. pub enum NodeType<V: FromAnyValue = ()> {
  25. Text {
  26. text: String,
  27. },
  28. Element {
  29. tag: String,
  30. namespace: Option<String>,
  31. attributes: FxHashMap<OwnedAttributeDiscription, OwnedAttributeValue<V>>,
  32. listeners: FxHashSet<String>,
  33. },
  34. Placeholder,
  35. }
  36. impl<S: State, V: FromAnyValue> Node<S, V> {
  37. pub(crate) fn new(node_type: NodeType<V>) -> Self {
  38. Node {
  39. state: S::default(),
  40. node_data: NodeData {
  41. element_id: None,
  42. node_type,
  43. node_id: NodeId(0),
  44. },
  45. }
  46. }
  47. /// get the mounted id of the node
  48. pub fn mounted_id(&self) -> Option<ElementId> {
  49. self.node_data.element_id
  50. }
  51. }
  52. #[derive(Debug, Clone, Hash, PartialEq, Eq)]
  53. pub struct OwnedAttributeDiscription {
  54. pub name: String,
  55. pub namespace: Option<String>,
  56. pub volatile: bool,
  57. }
  58. /// An attribute on a DOM node, such as `id="my-thing"` or
  59. /// `href="https://example.com"`.
  60. #[derive(Clone, Copy, Debug)]
  61. pub struct OwnedAttributeView<'a, V: FromAnyValue = ()> {
  62. /// The discription of the attribute.
  63. pub attribute: &'a OwnedAttributeDiscription,
  64. /// The value of the attribute.
  65. pub value: &'a OwnedAttributeValue<V>,
  66. }
  67. #[derive(Clone)]
  68. pub enum OwnedAttributeValue<V: FromAnyValue = ()> {
  69. Text(String),
  70. Float(f64),
  71. Int(i64),
  72. Bool(bool),
  73. Custom(V),
  74. None,
  75. }
  76. pub trait FromAnyValue {
  77. fn from_any_value(value: &dyn AnyValue) -> Self;
  78. }
  79. impl FromAnyValue for () {
  80. fn from_any_value(_: &dyn AnyValue) -> Self {}
  81. }
  82. impl<V: FromAnyValue> Debug for OwnedAttributeValue<V> {
  83. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  84. match self {
  85. Self::Text(arg0) => f.debug_tuple("Text").field(arg0).finish(),
  86. Self::Float(arg0) => f.debug_tuple("Float").field(arg0).finish(),
  87. Self::Int(arg0) => f.debug_tuple("Int").field(arg0).finish(),
  88. Self::Bool(arg0) => f.debug_tuple("Bool").field(arg0).finish(),
  89. Self::Custom(_) => f.debug_tuple("Any").finish(),
  90. Self::None => write!(f, "None"),
  91. }
  92. }
  93. }
  94. impl<V: FromAnyValue> From<BorrowedAttributeValue<'_>> for OwnedAttributeValue<V> {
  95. fn from(value: BorrowedAttributeValue<'_>) -> Self {
  96. match value {
  97. BorrowedAttributeValue::Text(text) => Self::Text(text.to_string()),
  98. BorrowedAttributeValue::Float(float) => Self::Float(float),
  99. BorrowedAttributeValue::Int(int) => Self::Int(int),
  100. BorrowedAttributeValue::Bool(bool) => Self::Bool(bool),
  101. BorrowedAttributeValue::Any(any) => Self::Custom(V::from_any_value(&*any)),
  102. BorrowedAttributeValue::None => Self::None,
  103. }
  104. }
  105. }
  106. impl<V: FromAnyValue> OwnedAttributeValue<V> {
  107. pub fn as_text(&self) -> Option<&str> {
  108. match self {
  109. OwnedAttributeValue::Text(text) => Some(text),
  110. _ => None,
  111. }
  112. }
  113. pub fn as_float(&self) -> Option<f64> {
  114. match self {
  115. OwnedAttributeValue::Float(float) => Some(*float),
  116. _ => None,
  117. }
  118. }
  119. pub fn as_int(&self) -> Option<i64> {
  120. match self {
  121. OwnedAttributeValue::Int(int) => Some(*int),
  122. _ => None,
  123. }
  124. }
  125. pub fn as_bool(&self) -> Option<bool> {
  126. match self {
  127. OwnedAttributeValue::Bool(bool) => Some(*bool),
  128. _ => None,
  129. }
  130. }
  131. pub fn as_none(&self) -> Option<()> {
  132. match self {
  133. OwnedAttributeValue::None => Some(()),
  134. _ => None,
  135. }
  136. }
  137. pub fn as_custom(&self) -> Option<&V> {
  138. match self {
  139. OwnedAttributeValue::Custom(custom) => Some(custom),
  140. _ => None,
  141. }
  142. }
  143. }