sgf_render/render/
options.rs

1use crate::{errors::UsageError, text::TileSet};
2
3use super::{GobanRange, GobanStyle};
4
5#[derive(Debug, Clone, Default)]
6pub struct RenderOptions {
7    pub node_description: NodeDescription,
8    pub goban_range: GobanRange,
9    pub style: GobanStyle,
10    pub viewbox_width: f64,
11    pub label_sides: BoardSideSet,
12    pub move_number_options: Option<MoveNumberOptions>,
13    pub draw_marks: bool,
14    pub draw_triangles: bool,
15    pub draw_circles: bool,
16    pub draw_squares: bool,
17    pub draw_selected: bool,
18    pub draw_dimmed: bool,
19    pub draw_labels: bool,
20    pub draw_lines: bool,
21    pub draw_arrows: bool,
22    pub tileset: TileSet,
23    pub kifu_mode: bool,
24}
25
26#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, clap::Parser)]
27pub struct NodeDescription {
28    /// Game number to display (for multi-game files).
29    #[arg(short, long, default_value_t = 0)]
30    pub game_number: u64,
31    /// Variation number to display (use `query` command for numbers).
32    #[arg(short, long, default_value_t = 0)]
33    pub variation: u64,
34    /// Node number in the variation to display.
35    #[arg(short, long, default_value = "last")]
36    pub node_number: NodeNumber,
37}
38
39#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
40pub enum NodeNumber {
41    Number(u64),
42    #[default]
43    Last,
44}
45
46impl std::str::FromStr for NodeNumber {
47    type Err = UsageError;
48
49    fn from_str(s: &str) -> Result<Self, Self::Err> {
50        match s {
51            "last" => Ok(NodeNumber::Last),
52            _ => {
53                let n = s
54                    .parse()
55                    .map_err(|_| UsageError::InvalidNodeNumber(s.to_string()))?;
56                Ok(NodeNumber::Number(n))
57            }
58        }
59    }
60}
61
62#[derive(Debug, Clone, Copy)]
63pub struct MoveNumberOptions {
64    pub start: u64,
65    pub end: Option<u64>,
66    pub count_from: u64,
67}
68
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
70pub enum BoardSide {
71    North,
72    East,
73    South,
74    West,
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
78pub struct BoardSideSet(u8);
79
80impl BoardSideSet {
81    pub fn is_empty(&self) -> bool {
82        self.0 == 0
83    }
84
85    pub fn contains(&self, side: BoardSide) -> bool {
86        self.0 & (1 << side as u8) != 0
87    }
88
89    pub fn insert(&mut self, side: BoardSide) {
90        self.0 |= 1 << side as u8
91    }
92}
93
94impl std::str::FromStr for BoardSideSet {
95    type Err = UsageError;
96
97    fn from_str(s: &str) -> Result<Self, Self::Err> {
98        let mut value = BoardSideSet::default();
99        for c in s.chars() {
100            match c {
101                'n' => value.insert(BoardSide::North),
102                'e' => value.insert(BoardSide::East),
103                's' => value.insert(BoardSide::South),
104                'w' => value.insert(BoardSide::West),
105                _ => return Err(UsageError::InvalidBoardSides),
106            }
107        }
108        Ok(value)
109    }
110}