dot2/
arrow.rs

1/// This enumeration represents all possible arrow edge
2/// as defined in [grapviz documentation](http://www.graphviz.org/content/arrow-shapes).
3#[derive(Clone, Copy, Hash, PartialEq, Eq)]
4pub enum Shape {
5    /// No arrow will be displayed
6    NoArrow,
7    /// Arrow that ends in a triangle. Basically a normal arrow.
8    /// NOTE: there is error in official documentation, this supports both fill and side clipping
9    Normal(crate::Fill, crate::Side),
10    /// Arrow ending in a small square box
11    Box(crate::Fill, crate::Side),
12    /// Arrow ending in a three branching lines also called crow's foot
13    Crow(crate::Side),
14    /// Arrow ending in a curve
15    Curve(crate::Side),
16    /// Arrow ending in an inverted curve
17    ICurve(crate::Fill, crate::Side),
18    /// Arrow ending in an diamond shaped rectangular shape.
19    Diamond(crate::Fill, crate::Side),
20    /// Arrow ending in a circle.
21    Dot(crate::Fill),
22    /// Arrow ending in an inverted triangle.
23    Inv(crate::Fill, crate::Side),
24    /// Arrow ending with a T shaped arrow.
25    Tee(crate::Side),
26    /// Arrow ending with a V shaped arrow.
27    Vee(crate::Side),
28}
29
30impl Shape {
31    /// Constructor which returns no arrow.
32    pub fn none() -> Self {
33        Self::NoArrow
34    }
35
36    /// Constructor which returns normal arrow.
37    pub fn normal() -> Self {
38        Self::Normal(crate::Fill::Filled, crate::Side::Both)
39    }
40
41    /// Constructor which returns a regular box arrow.
42    pub fn boxed() -> Self {
43        Self::Box(crate::Fill::Filled, crate::Side::Both)
44    }
45
46    /// Constructor which returns a regular crow arrow.
47    pub fn crow() -> Self {
48        Self::Crow(crate::Side::Both)
49    }
50
51    /// Constructor which returns a regular curve arrow.
52    pub fn curve() -> Self {
53        Self::Curve(crate::Side::Both)
54    }
55
56    /// Constructor which returns an inverted curve arrow.
57    pub fn icurve() -> Self {
58        Self::ICurve(crate::Fill::Filled, crate::Side::Both)
59    }
60
61    /// Constructor which returns a diamond arrow.
62    pub fn diamond() -> Self {
63        Self::Diamond(crate::Fill::Filled, crate::Side::Both)
64    }
65
66    /// Constructor which returns a circle shaped arrow.
67    pub fn dot() -> Self {
68        Self::Diamond(crate::Fill::Filled, crate::Side::Both)
69    }
70
71    /// Constructor which returns an inverted triangle arrow.
72    pub fn inv() -> Self {
73        Self::Inv(crate::Fill::Filled, crate::Side::Both)
74    }
75
76    /// Constructor which returns a T shaped arrow.
77    pub fn tee() -> Self {
78        Self::Tee(crate::Side::Both)
79    }
80
81    /// Constructor which returns a V shaped arrow.
82    pub fn vee() -> Self {
83        Self::Vee(crate::Side::Both)
84    }
85}
86
87impl std::fmt::Display for Shape {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        match self {
90            Self::Box(fill, side)
91            | Self::ICurve(fill, side)
92            | Self::Diamond(fill, side)
93            | Self::Inv(fill, side)
94            | Self::Normal(fill, side) => {
95                write!(f, "{fill}")?;
96                if matches!(side, crate::Side::Left | crate::Side::Right) {
97                    write!(f, "{side}")?;
98                }
99            }
100            Self::Dot(fill) => write!(f, "{fill}")?,
101            Self::Crow(side) | Self::Curve(side) | Self::Tee(side) | Self::Vee(side) => {
102                if matches!(side, crate::Side::Left | crate::Side::Right) {
103                    write!(f, "{side}")?;
104                }
105            }
106            Self::NoArrow => {}
107        };
108
109        let s = match self {
110            Self::NoArrow => "none",
111            Self::Normal(_, _) => "normal",
112            Self::Box(_, _) => "box",
113            Self::Crow(_) => "crow",
114            Self::Curve(_) => "curve",
115            Self::ICurve(_, _) => "icurve",
116            Self::Diamond(_, _) => "diamond",
117            Self::Dot(_) => "dot",
118            Self::Inv(_, _) => "inv",
119            Self::Tee(_) => "tee",
120            Self::Vee(_) => "vee",
121        };
122
123        write!(f, "{s}")
124    }
125}
126
127/// This structure holds all information that can describe an arrow connected to
128/// either start or end of an edge.
129#[derive(Clone, Hash, PartialEq, Eq)]
130pub struct Arrow {
131    pub arrows: Vec<Shape>,
132}
133
134impl Arrow {
135    /// Return `true` if this is a default arrow.
136    pub(crate) fn is_default(&self) -> bool {
137        self.arrows.is_empty()
138    }
139
140    /// Arrow constructor which returns a default arrow
141    pub fn default() -> Self {
142        Self { arrows: vec![] }
143    }
144
145    /// Arrow constructor which returns an empty arrow
146    pub fn none() -> Self {
147        Self {
148            arrows: vec![Shape::NoArrow],
149        }
150    }
151
152    /// Arrow constructor which returns a regular triangle arrow, without modifiers
153    pub fn normal() -> Self {
154        Self {
155            arrows: vec![Shape::normal()],
156        }
157    }
158
159    /// Arrow constructor which returns an arrow created by a given Shape.
160    pub fn from_arrow(arrow: Shape) -> Self {
161        Self {
162            arrows: vec![arrow],
163        }
164    }
165}
166
167impl std::fmt::Display for Arrow {
168    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169        for arrow in &self.arrows {
170            write!(f, "{arrow}")?;
171        }
172
173        Ok(())
174    }
175}
176
177impl From<[Shape; 2]> for Arrow {
178    fn from(shape: [Shape; 2]) -> Self {
179        Self {
180            arrows: vec![shape[0], shape[1]],
181        }
182    }
183}
184
185impl From<[Shape; 3]> for Arrow {
186    fn from(shape: [Shape; 3]) -> Self {
187        Self {
188            arrows: vec![shape[0], shape[1], shape[2]],
189        }
190    }
191}
192
193impl From<[Shape; 4]> for Arrow {
194    fn from(shape: [Shape; 4]) -> Self {
195        Self {
196            arrows: vec![shape[0], shape[1], shape[2], shape[3]],
197        }
198    }
199}