Skip to main content

example3/
example3.rs

1//! Example on how to use the [`Layouter::embed_with_visualize_with_source`] to embed a tree and
2//! visualize it with the source code.
3//! We use the data from the syntree crate's example `calculator` -- "256 / 2 + 64 * 2"
4//! The tree has the following structure:
5//! ```text
6//! # Tree:
7//! Operation@0..16
8//!   Number@0..3
9//!     Number@0..3 "256"
10//!   Whitespace@3..4 " "
11//!   Operator@4..5
12//!     Div@4..5 "/"
13//!   Whitespace@5..6 " "
14//!   Number@6..7
15//!     Number@6..7 "2"
16//!   Whitespace@7..8 " "
17//!   Operator@8..9
18//!     Plus@8..9 "+"
19//!   Whitespace@9..10 " "
20//!   Operation@10..16
21//!     Number@10..12
22//!       Number@10..12 "64"
23//!     Whitespace@12..13 " "
24//!     Operator@13..14
25//!       Mul@13..14 "*"
26//!     Whitespace@14..15 " "
27//!     Number@15..16
28//!       Number@15..16 "2"
29//!```
30use std::fmt::Display;
31
32use anyhow::Result;
33use syntree_layout::Layouter;
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36#[allow(non_camel_case_types)]
37enum Syntax {
38    Number,
39    Plus,
40    Div,
41    Mul,
42    Whitespace,
43    Operator,
44    Operation,
45}
46
47impl Display for Syntax {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        let s = match self {
50            Syntax::Number => "Number",
51            Syntax::Plus => "Plus",
52            Syntax::Div => "Div",
53            Syntax::Mul => "Mul",
54            Syntax::Whitespace => "Whitespace",
55            Syntax::Operator => "Operator",
56            Syntax::Operation => "Operation",
57        };
58        write!(f, "{}", s)
59    }
60}
61
62fn main() -> Result<()> {
63    let source = "256 / 2 + 64 * 2";
64    let tree = syntree::tree! {
65        Syntax::Operation => {
66            Syntax::Number => {
67                (Syntax::Number, 3),
68            },
69            (Syntax::Whitespace, 1),
70            Syntax::Operator => {
71                (Syntax::Div, 1),
72            },
73           (Syntax::Whitespace, 1),
74            Syntax::Number => {
75                (Syntax::Number, 1),
76            },
77            (Syntax::Whitespace, 1),
78            Syntax::Operator => {
79                (Syntax::Plus, 1),
80            },
81            (Syntax::Whitespace, 1),
82            Syntax::Operation => {
83                Syntax::Number => {
84                    (Syntax::Number, 2),
85                },
86                (Syntax::Whitespace, 1),
87                Syntax::Operator => {
88                    (Syntax::Mul, 1),
89                },
90                (Syntax::Whitespace, 1),
91                Syntax::Number => {
92                    (Syntax::Number, 1),
93                },
94            },
95
96        }
97    };
98
99    // Embed the tree with the source code.
100    Layouter::new(&tree)
101        .with_file_path("examples/example3_1.svg")
102        .embed_with_source(source)
103        .map_err(|e| anyhow::anyhow!(e))?
104        .write()
105        .map_err(|e| anyhow::anyhow!(e))?;
106    // Embed the tree with the source code and `Display` trait.
107    Layouter::new(&tree)
108        .with_file_path("examples/example3_2.svg")
109        .embed_with_source_and_display(source)
110        .map_err(|e| anyhow::anyhow!(e))?
111        .write()
112        .map_err(|e| anyhow::anyhow!(e))
113}