dotavious/attributes/
point.rs

1use crate::dot::DotString;
2use std::borrow::Cow;
3
4pub struct Point {
5    pub x: f32,
6    pub y: f32,
7    pub z: Option<f32>,
8
9    /// specify that the node position should not change.
10    pub force_pos: bool,
11}
12
13impl Point {
14    pub fn new_2d(x: f32, y: f32) -> Self {
15        Self::new(x, y, None, false)
16    }
17
18    pub fn new_3d(x: f32, y: f32, z: f32) -> Self {
19        Self::new(x, y, Some(z), false)
20    }
21
22    pub fn new(x: f32, y: f32, z: Option<f32>, force_pos: bool) -> Self {
23        Self { x, y, z, force_pos }
24    }
25}
26
27impl<'a> DotString<'a> for Point {
28    fn dot_string(&self) -> Cow<'a, str> {
29        let mut slice = format!("{:.1},{:.1}", self.x, self.y);
30        if self.z.is_some() {
31            slice.push_str(format!(",{:.1}", self.z.unwrap()).as_str());
32        }
33        if self.force_pos {
34            slice.push_str("!")
35        }
36        slice.into()
37    }
38}
39
40#[cfg(test)]
41mod test {
42    use crate::attributes::Point;
43    use crate::DotString;
44
45    #[test]
46    fn dot_string() {
47        assert_eq!("1.0,2.0", Point::new_2d(1.0, 2.0).dot_string());
48        assert_eq!("1.0,2.0,0.0", Point::new_3d(1.0, 2.0, 0.0).dot_string());
49        assert_eq!("1.0,2.0!", Point::new(1.0, 2.0, None, true).dot_string());
50        assert_eq!(
51            "1.0,2.0,0.0!",
52            Point::new(1.0, 2.0, Some(0.0), true).dot_string()
53        );
54    }
55}