sable-canvas/src/node/mod.rs@main
raw
1mod file;
2mod group;
3mod link;
4mod text;
5
6use crate::{NodeId, PixelCoordinate, PixelDimension, color::Color};
7
8pub use self::{
9 file::FileNode,
10 group::{Background, BackgroundStyle, GroupNode},
11 link::LinkNode,
12 text::TextNode,
13};
14
15#[derive(
17 Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
18)]
19pub struct GenericNode {
20 pub id: NodeId,
22 x: PixelCoordinate,
23 y: PixelCoordinate,
24 width: PixelDimension,
25 height: PixelDimension,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 color: Option<Color>,
28}
29
30impl GenericNode {
31 #[must_use]
33 pub const fn new(
34 id: NodeId,
35 x: PixelCoordinate,
36 y: PixelCoordinate,
37 width: PixelDimension,
38 height: PixelDimension,
39 color: Option<Color>,
40 ) -> Self {
41 Self {
42 id,
43 x,
44 y,
45 width,
46 height,
47 color,
48 }
49 }
50}
51
52pub trait GenericNodeInfo {
54 fn id(&self) -> &NodeId;
56 fn x(&self) -> PixelCoordinate;
58 fn y(&self) -> PixelCoordinate;
60 fn width(&self) -> PixelDimension;
62 fn height(&self) -> PixelDimension;
64 fn color(&self) -> &Option<Color>;
66}
67
68impl GenericNodeInfo for GenericNode {
69 fn id(&self) -> &NodeId {
70 &self.id
71 }
72
73 fn x(&self) -> PixelCoordinate {
74 self.x
75 }
76
77 fn y(&self) -> PixelCoordinate {
78 self.y
79 }
80
81 fn width(&self) -> PixelDimension {
82 self.width
83 }
84
85 fn height(&self) -> PixelDimension {
86 self.height
87 }
88
89 fn color(&self) -> &Option<Color> {
90 &self.color
91 }
92}
93
94#[derive(Debug, serde::Serialize, serde::Deserialize)]
96#[serde(tag = "type", rename_all = "camelCase")]
97pub enum Node {
98 Text(TextNode),
102 File(FileNode),
106 Link(LinkNode),
110 Group(GroupNode),
114}
115
116impl From<GroupNode> for Node {
117 fn from(node: GroupNode) -> Self {
118 Self::Group(node)
119 }
120}
121
122impl From<TextNode> for Node {
123 fn from(node: TextNode) -> Self {
124 Self::Text(node)
125 }
126}
127
128impl From<FileNode> for Node {
129 fn from(node: FileNode) -> Self {
130 Self::File(node)
131 }
132}
133
134impl From<LinkNode> for Node {
135 fn from(node: LinkNode) -> Self {
136 Self::Link(node)
137 }
138}
139
140impl GenericNodeInfo for Node {
141 fn id(&self) -> &NodeId {
142 match &self {
143 Self::Text(node) => node.id(),
144 Self::File(node) => node.id(),
145 Self::Link(node) => node.id(),
146 Self::Group(node) => node.id(),
147 }
148 }
149
150 fn x(&self) -> PixelCoordinate {
151 match &self {
152 Self::Text(node) => node.x(),
153 Self::File(node) => node.x(),
154 Self::Link(node) => node.x(),
155 Self::Group(node) => node.x(),
156 }
157 }
158
159 fn y(&self) -> PixelCoordinate {
160 match &self {
161 Self::Text(node) => node.y(),
162 Self::File(node) => node.y(),
163 Self::Link(node) => node.y(),
164 Self::Group(node) => node.y(),
165 }
166 }
167
168 fn width(&self) -> PixelDimension {
169 match &self {
170 Self::Text(node) => node.width(),
171 Self::File(node) => node.width(),
172 Self::Link(node) => node.width(),
173 Self::Group(node) => node.width(),
174 }
175 }
176
177 fn height(&self) -> PixelDimension {
178 match &self {
179 Self::Text(node) => node.height(),
180 Self::File(node) => node.height(),
181 Self::Link(node) => node.height(),
182 Self::Group(node) => node.height(),
183 }
184 }
185
186 fn color(&self) -> &Option<Color> {
187 match &self {
188 Self::Text(node) => node.color(),
189 Self::File(node) => node.color(),
190 Self::Link(node) => node.color(),
191 Self::Group(node) => node.color(),
192 }
193 }
194}
195