jsoncanvas/node/
mod.rs

1use crate::color::Color;
2use crate::NodeId;
3use crate::PixelCoordinate;
4use crate::PixelDimension;
5use ambassador::{delegatable_trait, Delegate};
6use serde::{Deserialize, Serialize};
7
8mod file;
9mod group;
10mod link;
11mod text;
12
13pub use file::FileNode;
14pub use group::{Background, BackgroundStyle, GroupNode};
15pub use link::LinkNode;
16pub use text::TextNode;
17
18#[derive(Debug, Serialize, Deserialize)]
19pub struct GenericNode {
20    pub id: NodeId,
21    x: PixelCoordinate,
22    y: PixelCoordinate,
23    width: PixelDimension,
24    height: PixelDimension,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    color: Option<crate::color::Color>,
27}
28
29impl GenericNode {
30    pub fn new(
31        id: NodeId,
32        x: PixelCoordinate,
33        y: PixelCoordinate,
34        width: PixelDimension,
35        height: PixelDimension,
36        color: Option<Color>,
37    ) -> Self {
38        Self {
39            id,
40            x,
41            y,
42            width,
43            height,
44            color,
45        }
46    }
47}
48
49#[delegatable_trait]
50pub trait GenericNodeInfo {
51    fn id(&self) -> &NodeId;
52    fn get_x(&self) -> PixelCoordinate;
53    fn get_y(&self) -> PixelCoordinate;
54    fn get_width(&self) -> PixelDimension;
55    fn get_height(&self) -> PixelDimension;
56    fn color(&self) -> &Option<Color>;
57}
58
59// This must come below the #[delegatable_trait] trait; see
60// https://github.com/hobofan/ambassador/issues/45#issuecomment-1901574140
61pub use ambassador_impl_GenericNodeInfo;
62
63impl GenericNodeInfo for GenericNode {
64    fn id(&self) -> &NodeId {
65        &self.id
66    }
67
68    fn get_x(&self) -> PixelCoordinate {
69        self.x
70    }
71
72    fn get_y(&self) -> PixelCoordinate {
73        self.y
74    }
75
76    fn get_width(&self) -> PixelDimension {
77        self.width
78    }
79
80    fn get_height(&self) -> PixelDimension {
81        self.height
82    }
83
84    fn color(&self) -> &Option<Color> {
85        &self.color
86    }
87}
88
89#[derive(Debug, Delegate, Serialize, Deserialize)]
90#[delegate(GenericNodeInfo)]
91#[serde(tag = "type", rename_all = "camelCase")]
92pub enum Node {
93    Text(TextNode),
94    File(FileNode),
95    Link(LinkNode),
96    Group(GroupNode),
97}
98
99impl From<GroupNode> for Node {
100    fn from(node: GroupNode) -> Self {
101        Node::Group(node)
102    }
103}
104
105impl From<TextNode> for Node {
106    fn from(node: TextNode) -> Self {
107        Node::Text(node)
108    }
109}
110
111impl From<FileNode> for Node {
112    fn from(node: FileNode) -> Self {
113        Node::File(node)
114    }
115}
116
117impl From<LinkNode> for Node {
118    fn from(node: LinkNode) -> Self {
119        Node::Link(node)
120    }
121}