xdot/xdot_parse/draw/
attrs.rs

1//! Types reused for drawing things.
2use std::str::FromStr;
3
4use bitflags::bitflags;
5
6/// RGBA color representation with 8 bit per channel.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8#[cfg_attr(
9    feature = "pyo3",
10    pyo3::pyclass(eq, get_all, set_all, module = "xdot_rs.draw")
11)]
12pub struct Rgba {
13    pub r: u8,
14    pub g: u8,
15    pub b: u8,
16    pub a: u8,
17}
18impl Default for Rgba {
19    fn default() -> Self {
20        Rgba {
21            r: 0,
22            g: 0,
23            b: 0,
24            a: 0xff,
25        }
26    }
27}
28
29/// Line style for node borders and edges.
30/// See [here](https://graphviz.org/docs/attr-types/style/).
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
32#[cfg_attr(
33    feature = "pyo3",
34    pyo3::pyclass(eq, eq_int, get_all, set_all, module = "xdot_rs.draw")
35)]
36pub enum Style {
37    Dashed,
38    Dotted,
39    #[default]
40    Solid,
41    Invis,
42    Bold,
43    // TODO: "tapered" for edges only
44}
45impl FromStr for Style {
46    type Err = String;
47    fn from_str(s: &str) -> Result<Self, Self::Err> {
48        use Style::*;
49        Ok(match s {
50            "dashed" => Dashed,
51            "dotted" => Dotted,
52            "solid" => Solid,
53            "invis" => Invis,
54            "bold" => Bold,
55            s => return Err(s.to_owned()),
56        })
57    }
58}
59
60bitflags! {
61    /// Font weight and decorations.
62    /// Matches values defined [here](https://graphviz.org/docs/outputs/canon/#xdot).
63    #[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
64    #[cfg_attr(
65        feature = "pyo3",
66        pyo3::pyclass(eq, module = "xdot_rs.draw")
67    )]
68    pub struct FontCharacteristics: u128 {
69        const BOLD           = 0b00000001;
70        const ITALIC         = 0b00000010;
71        const UNDERLINE      = 0b00000100;
72        const SUPERSCRIPT    = 0b00001000;
73        const SUBSCRIPT      = 0b00010000;
74        const STRIKE_THROUGH = 0b00100000;
75        const OVERLINE       = 0b01000000;
76    }
77}
78#[cfg(feature = "pyo3")]
79#[pyo3::pymethods]
80impl FontCharacteristics {
81    #[new]
82    #[pyo3(signature = (
83        bold=false,
84        italic=false,
85        underline=false,
86        superscript=false,
87        subscript=false,
88        strike_through=false,
89        overline=false,
90    ))]
91    fn new(
92        bold: bool,
93        italic: bool,
94        underline: bool,
95        superscript: bool,
96        subscript: bool,
97        strike_through: bool,
98        overline: bool,
99    ) -> Self {
100        let mut fc = FontCharacteristics::empty();
101        fc.set_bold(bold);
102        fc.set_italic(italic);
103        fc.set_underline(underline);
104        fc.set_superscript(superscript);
105        fc.set_subscript(subscript);
106        fc.set_strike_through(strike_through);
107        fc.set_overline(overline);
108        fc
109    }
110    fn __repr__(&self) -> String {
111        format!("{:?}", self)
112    }
113}
114impl_bitflags_accessors!(
115    FontCharacteristics,
116    bold,
117    italic,
118    underline,
119    superscript,
120    subscript,
121    strike_through,
122    overline,
123);