xdot/xdot_parse/draw/
attrs.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! Types reused for drawing things.
use std::str::FromStr;

use bitflags::bitflags;

/// RGBA color representation with 8 bit per channel.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
    feature = "pyo3",
    pyo3::pyclass(eq, get_all, set_all, module = "xdot_rs.draw")
)]
pub struct Rgba {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}
impl Default for Rgba {
    fn default() -> Self {
        Rgba {
            r: 0,
            g: 0,
            b: 0,
            a: 0xff,
        }
    }
}

/// Line style for node borders and edges.
/// See [here](https://graphviz.org/docs/attr-types/style/).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(
    feature = "pyo3",
    pyo3::pyclass(eq, eq_int, get_all, set_all, module = "xdot_rs.draw")
)]
pub enum Style {
    Dashed,
    Dotted,
    #[default]
    Solid,
    Invis,
    Bold,
    // TODO: "tapered" for edges only
}
impl FromStr for Style {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use Style::*;
        Ok(match s {
            "dashed" => Dashed,
            "dotted" => Dotted,
            "solid" => Solid,
            "invis" => Invis,
            "bold" => Bold,
            s => return Err(s.to_owned()),
        })
    }
}

bitflags! {
    /// Font weight and decorations.
    /// Matches values defined [here](https://graphviz.org/docs/outputs/canon/#xdot).
    #[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
    #[cfg_attr(
        feature = "pyo3",
        pyo3::pyclass(eq, module = "xdot_rs.draw")
    )]
    pub struct FontCharacteristics: u128 {
        const BOLD           = 0b00000001;
        const ITALIC         = 0b00000010;
        const UNDERLINE      = 0b00000100;
        const SUPERSCRIPT    = 0b00001000;
        const SUBSCRIPT      = 0b00010000;
        const STRIKE_THROUGH = 0b00100000;
        const OVERLINE       = 0b01000000;
    }
}
#[cfg(feature = "pyo3")]
#[pyo3::pymethods]
impl FontCharacteristics {
    #[new]
    #[pyo3(signature = (
        bold=false,
        italic=false,
        underline=false,
        superscript=false,
        subscript=false,
        strike_through=false,
        overline=false,
    ))]
    fn new(
        bold: bool,
        italic: bool,
        underline: bool,
        superscript: bool,
        subscript: bool,
        strike_through: bool,
        overline: bool,
    ) -> Self {
        let mut fc = FontCharacteristics::empty();
        fc.set_bold(bold);
        fc.set_italic(italic);
        fc.set_underline(underline);
        fc.set_superscript(superscript);
        fc.set_subscript(subscript);
        fc.set_strike_through(strike_through);
        fc.set_overline(overline);
        fc
    }
    fn __repr__(&self) -> String {
        format!("{:?}", self)
    }
}
impl_bitflags_accessors!(
    FontCharacteristics,
    bold,
    italic,
    underline,
    superscript,
    subscript,
    strike_through,
    overline,
);