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}