jsoncanvas/
lib.rs

1//! # jsoncanvas
2//!
3//! `jsoncanvas` is a library for creating and manipulating JSON objects representing a canvas.
4//!
5//! Specification source: <https://jsoncanvas.org/>
6//!
7//! ## Example
8//!
9//! ```
10//! use jsoncanvas::JsonCanvas;
11//! let s: String = "{\"nodes\":[{\"id\":\"id7\",\"x\":0,\"y\":0,\"width\":100,\"height\":100,\"background\":\"path/to/image.png\",\"type\":\"group\"},{\"id\":\"id5\",\"x\":0,\"y\":0,\"width\":100,\"height\":100,\"color\":\"#ff0000\",\"label\":\"Label\",\"type\":\"group\"},{\"id\":\"id2\",\"x\":0,\"y\":0,\"width\":100,\"height\":100,\"color\":\"1\",\"file\":\"dir/to/path/file.png\",\"type\":\"file\"},{\"id\":\"id4\",\"x\":0,\"y\":0,\"width\":100,\"height\":100,\"color\":\"1\",\"url\":\"https://www.google.com\",\"type\":\"link\"},{\"id\":\"id6\",\"x\":0,\"y\":0,\"width\":100,\"height\":100,\"type\":\"group\"},{\"id\":\"id3\",\"x\":0,\"y\":0,\"width\":100,\"height\":100,\"color\":\"1\",\"file\":\"dir/to/path/file.png\",\"subpath\":\"#here\",\"type\":\"file\"},{\"id\":\"id8\",\"x\":0,\"y\":0,\"width\":100,\"height\":100,\"background\":\"path/to/image.png\",\"backgroundStyle\":\"cover\",\"type\":\"group\"},{\"id\":\"id\",\"x\":0,\"y\":0,\"width\":100,\"height\":100,\"color\":\"1\",\"text\":\"Test\",\"type\":\"text\"}],\"edges\":[{\"id\":\"edge2\",\"fromNode\":\"node3\",\"toNode\":\"node4\",\"color\":\"5\",\"label\":\"edge label\",\"toSide\":\"left\",\"toEnd\":\"arrow\"},{\"id\":\"edge1\",\"fromNode\":\"node1\",\"toNode\":\"node2\",\"toSide\":\"left\",\"toEnd\":\"arrow\"}]}".to_string();
12//! let canvas: JsonCanvas = s.parse().unwrap();
13//!
14//! let _s = canvas.to_string();
15//! ```
16//!
17//! ## Complete example
18//!
19//! ```
20//!    use hex_color::HexColor;
21//!    use jsoncanvas::color::{Color, PresetColor};
22//!    use jsoncanvas::edge::{Edge, End, Side};
23//!    use jsoncanvas::node::{
24//!        Background, BackgroundStyle, FileNode, GroupNode, LinkNode, Node, TextNode,
25//!    };
26//!    use jsoncanvas::JsonCanvas;
27//!    use std::path::PathBuf;
28//!    use url::Url;
29//!
30//!    // Color
31//!    let color1 = Color::Preset(PresetColor::Red);
32//!    let color2 = Color::Color(HexColor::parse("#ff0000").unwrap());
33//!
34//!    let serialized_color1 = serde_json::to_string(&color1).unwrap();
35//!    let serialized_color2 = serde_json::to_string(&color2).unwrap();
36//!
37//!    println!("serialized1 = {}", serialized_color1);
38//!    println!("serialized2 = {}", serialized_color2);
39//!
40//!    // Text Node
41//!    let node1: Node = Node::Text(TextNode::new(
42//!        "id".parse().unwrap(),
43//!        0,
44//!        0,
45//!        100,
46//!        100,
47//!        Some(Color::Preset(PresetColor::Red)),
48//!        "This is a test".to_string(),
49//!    ));
50//!
51//!    // File Node
52//!    let node2: Node = Node::File(FileNode::new(
53//!        "id2".parse().unwrap(),
54//!        0,
55//!        0,
56//!        100,
57//!        100,
58//!        Some(Color::Preset(PresetColor::Red)),
59//!        PathBuf::from("dir/to/path/file.png"),
60//!        None,
61//!    ));
62//!    let node3: Node = Node::File(FileNode::new(
63//!        "id3".parse().unwrap(),
64//!        0,
65//!        0,
66//!        100,
67//!        100,
68//!        Some(color1),
69//!        PathBuf::from("dir/to/path/file.png"),
70//!        Some("#here".parse().unwrap()),
71//!    ));
72//!
73//!    // Link Node
74//!    let node4: Node = Node::Link(LinkNode::new(
75//!        "id4".parse().unwrap(),
76//!        0,
77//!        0,
78//!        100,
79//!        100,
80//!        Some(Color::Preset(PresetColor::Red)),
81//!        Url::parse("https://julienduroure.com").unwrap(),
82//!    ));
83//!
84//!    // Group Node
85//!    let node5: Node = Node::Group(GroupNode::new(
86//!        "id5".parse().unwrap(),
87//!        0,
88//!        0,
89//!        100,
90//!        100,
91//!        Some(color2),
92//!        Some("Label".to_string()),
93//!        None,
94//!    ));
95//!    let node6: Node = Node::Group(GroupNode::new(
96//!        "id6".parse().unwrap(),
97//!        0,
98//!        0,
99//!        100,
100//!        100,
101//!        None,
102//!        None,
103//!        None,
104//!    ));
105//!    let node7: Node = Node::Group(GroupNode::new(
106//!        "id7".parse().unwrap(),
107//!        0,
108//!        0,
109//!        100,
110//!        100,
111//!        None,
112//!        None,
113//!        Some(Background::new(PathBuf::from("path/to/image.png"), None)),
114//!    ));
115//!    let node8: Node = Node::Group(GroupNode::new(
116//!        "id8".parse().unwrap(),
117//!        0,
118//!        0,
119//!        100,
120//!        100,
121//!        None,
122//!        None,
123//!        Some(Background::new(
124//!            PathBuf::from("path/to/image.png"),
125//!            Some(BackgroundStyle::Cover),
126//!        )),
127//!    ));
128//!
129//!    let serialized_node1: String = serde_json::to_string(&node1).unwrap();
130//!    let serialized_node2 = serde_json::to_string(&node2).unwrap();
131//!    let serialized_node3 = serde_json::to_string(&node3).unwrap();
132//!    let serialized_node4 = serde_json::to_string(&node4).unwrap();
133//!    let serialized_node5 = serde_json::to_string(&node5).unwrap();
134//!    let serialized_node6 = serde_json::to_string(&node6).unwrap();
135//!    let serialized_node7 = serde_json::to_string(&node7).unwrap();
136//!    let serialized_node8 = serde_json::to_string(&node8).unwrap();
137//!
138//!    println!("serialized node 1= {}", serialized_node1);
139//!    println!("serialized node 2= {}", serialized_node2);
140//!    println!("serialized node 3= {}", serialized_node3);
141//!    println!("serialized node 4= {}", serialized_node4);
142//!    println!("serialized node 5= {}", serialized_node5);
143//!    println!("serialized node 6= {}", serialized_node6);
144//!    println!("serialized node 7= {}", serialized_node7);
145//!    println!("serialized node 8= {}", serialized_node8);
146//!
147//!    // Edge
148//!
149//!    let edge1 = Edge::new(
150//!        "edge1".parse().unwrap(),
151//!        "id".parse().unwrap(),
152//!        None,
153//!        None,
154//!        "id2".parse().unwrap(),
155//!        Some(Side::Left),
156//!        Some(End::Arrow),
157//!        None,
158//!        None,
159//!    );
160//!    let edge2 = Edge::new(
161//!        "edge2".parse().unwrap(),
162//!        "id3".parse().unwrap(),
163//!        None,
164//!        None,
165//!        "id4".parse().unwrap(),
166//!        Some(Side::Left),
167//!        Some(End::Arrow),
168//!        Some(Color::Preset(PresetColor::Cyan)),
169//!        Some("edge label".to_string()),
170//!    );
171//!
172//!    let serialized_edge1 = serde_json::to_string(&edge1).unwrap();
173//!    let serialized_edge2 = serde_json::to_string(&edge2).unwrap();
174//!
175//!    println!("serialized edge 1= {}", serialized_edge1);
176//!    println!("serialized edge 2= {}", serialized_edge2);
177//!
178//!    // JSON Canvas
179//!    let mut canvas = JsonCanvas::default();
180//!
181//!    let empty_canvas = canvas.to_string();
182//!    println!("empty canvas = {}", empty_canvas);
183//!    canvas = empty_canvas.parse().unwrap();
184//!
185//!    canvas.add_node(node1).unwrap();
186//!    canvas.add_node(node2).unwrap();
187//!    canvas.add_node(node3).unwrap();
188//!    canvas.add_node(node4).unwrap();
189//!    canvas.add_node(node5).unwrap();
190//!    canvas.add_node(node6).unwrap();
191//!    canvas.add_node(node7).unwrap();
192//!    canvas.add_node(node8).unwrap();
193//!
194//!    canvas.add_edge(edge1).unwrap();
195//!    canvas.add_edge(edge2).unwrap();
196//!
197//!    let serialized_canvas = canvas.to_string();
198//!
199//!    println!("serialized canvas = {}", serialized_canvas);
200//!
201//!    let jsoncanvas_deserialized: JsonCanvas = serialized_canvas.parse().unwrap();
202//!    println!("deserialized canvas = {:?}", jsoncanvas_deserialized);
203//! ```
204//!
205//! ## Available structs
206//!
207//! ```
208//! use hex_color::HexColor;
209//! use jsoncanvas::color::{Color, PresetColor};
210//! use jsoncanvas::edge::{Edge, End, Side};
211//! use jsoncanvas::node::{
212//!     Background, BackgroundStyle, FileNode, GroupNode, LinkNode, Node, TextNode,
213//! };
214//! use jsoncanvas::JsonCanvas;
215//! use std::path::PathBuf;
216//! use url::Url;
217//! ```
218
219// pub type NodeId = String;
220// pub type EdgeId = String;
221pub type PixelCoordinate = i64;
222pub type PixelDimension = u64;
223
224pub mod color;
225pub mod edge;
226mod id;
227pub mod jsoncanvas;
228pub mod node;
229
230pub use id::{EdgeId, NodeId};
231pub use jsoncanvas::JsonCanvas;
232pub use jsoncanvas::JsonCanvasError;
233pub use node::{Background, BackgroundStyle, FileNode, GroupNode, LinkNode, Node, TextNode};
234
235#[cfg(test)]
236mod test {
237    use hex_color::HexColor;
238
239    #[test]
240    fn test() {
241        use super::color::{Color, PresetColor};
242        use super::edge::{Edge, End, Side};
243        use super::jsoncanvas::JsonCanvas;
244        use super::node::{
245            Background, BackgroundStyle, FileNode, GroupNode, LinkNode, Node, TextNode,
246        };
247        use std::path::PathBuf;
248        use url::Url;
249
250        // Color
251        let color1 = Color::Preset(PresetColor::Red);
252        let color2 = Color::Color(HexColor::parse("#ff0000").unwrap());
253
254        // Text Node
255        let node1: Node = TextNode::new(
256            "id".parse().unwrap(),
257            0,
258            0,
259            100,
260            100,
261            Some(Color::Preset(PresetColor::Red)),
262            "This is a test".to_string(),
263        )
264        .into();
265
266        // File Node
267        let node2: Node = FileNode::new(
268            "id2".parse().unwrap(),
269            0,
270            0,
271            100,
272            100,
273            Some(Color::Preset(PresetColor::Red)),
274            PathBuf::from("dir/to/path/file.png"),
275            None,
276        )
277        .into();
278        let node3: Node = FileNode::new(
279            "id3".parse().unwrap(),
280            0,
281            0,
282            100,
283            100,
284            Some(color1),
285            PathBuf::from("dir/to/path/file.png"),
286            Some("#here".to_string()),
287        )
288        .into();
289
290        // Link Node
291        let node4: Node = LinkNode::new(
292            "id4".parse().unwrap(),
293            0,
294            0,
295            100,
296            100,
297            Some(Color::Preset(PresetColor::Red)),
298            Url::parse("https://julienduroure.com").unwrap(),
299        )
300        .into();
301
302        // Group Node
303        let node5: Node = GroupNode::new(
304            "id5".parse().unwrap(),
305            0,
306            0,
307            100,
308            100,
309            Some(color2),
310            Some("Label".to_string()),
311            None,
312        )
313        .into();
314        let node6: Node =
315            GroupNode::new("id6".parse().unwrap(), 0, 0, 100, 100, None, None, None).into();
316        let node7: Node = GroupNode::new(
317            "id7".parse().unwrap(),
318            0,
319            0,
320            100,
321            100,
322            None,
323            None,
324            Some(Background::new(PathBuf::from("path/to/image.png"), None)),
325        )
326        .into();
327        let node8: Node = GroupNode::new(
328            "id8".parse().unwrap(),
329            0,
330            0,
331            100,
332            100,
333            None,
334            None,
335            Some(Background::new(
336                PathBuf::from("path/to/image.png"),
337                Some(BackgroundStyle::Cover),
338            )),
339        )
340        .into();
341
342        // Edge
343
344        let edge1 = Edge::new(
345            "edge1".parse().unwrap(),
346            "id".parse().unwrap(),
347            None,
348            None,
349            "id2".parse().unwrap(),
350            Some(Side::Left),
351            Some(End::Arrow),
352            None,
353            None,
354        );
355        let edge2 = Edge::new(
356            "edge2".parse().unwrap(),
357            "id3".parse().unwrap(),
358            None,
359            None,
360            "id4".parse().unwrap(),
361            Some(Side::Left),
362            Some(End::Arrow),
363            Some(Color::Preset(PresetColor::Cyan)),
364            Some("edge label".to_string()),
365        );
366
367        // JSON Canvas
368        let mut canvas = JsonCanvas::default();
369        canvas.add_node(node1).unwrap();
370        canvas.add_node(node2).unwrap();
371        canvas.add_node(node3).unwrap();
372        canvas.add_node(node4).unwrap();
373        canvas.add_node(node5).unwrap();
374        canvas.add_node(node6).unwrap();
375        canvas.add_node(node7).unwrap();
376        canvas.add_node(node8).unwrap();
377
378        canvas.add_edge(edge1).unwrap();
379        canvas.add_edge(edge2).unwrap();
380
381        let serialized_canvas = canvas.to_string();
382
383        println!("serialized canvas = {}", serialized_canvas);
384
385        ///////////////////////////// Deserialization /////////////////////////////
386
387        // let deserialized_node1: Node = serde_json::from_str(&serialized_node1).unwrap();
388        // println!("deserialized node 1= {:?}", deserialized_node1);
389
390        // let deseralied_edge1: Edge = serde_json::from_str(&serialized_edge1).unwrap();
391        // println!("deserialized edge 1= {:?}", deseralied_edge1);
392
393        let _jsoncanvas_deserialized: JsonCanvas = serialized_canvas.parse().unwrap();
394    }
395}