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
/// Border is a representation of a cells's borders (left, right, top, bottom, and the corners)
#[derive(Debug, Clone, Default, Eq, PartialEq)]
pub struct Border<T = char> {
    /// A character for a top.
    pub top: Option<T>,
    /// A character for a bottom.
    pub bottom: Option<T>,
    /// A character for a left.
    pub left: Option<T>,
    /// A character for a right.
    pub right: Option<T>,
    /// A character for a left top corner.
    pub left_top_corner: Option<T>,
    /// A character for a left bottom corner.
    pub left_bottom_corner: Option<T>,
    /// A character for a right top corner.
    pub right_top_corner: Option<T>,
    /// A character for a right bottom corner.
    pub right_bottom_corner: Option<T>,
}

impl<T> Border<T> {
    /// This function constructs a cell borders with all sides set.
    #[allow(clippy::too_many_arguments)]
    pub fn full(
        top: T,
        bottom: T,
        left: T,
        right: T,
        top_left: T,
        top_right: T,
        bottom_left: T,
        bottom_right: T,
    ) -> Self {
        Self {
            top: Some(top),
            bottom: Some(bottom),
            right: Some(right),
            right_top_corner: Some(top_right),
            right_bottom_corner: Some(bottom_right),
            left: Some(left),
            left_bottom_corner: Some(bottom_left),
            left_top_corner: Some(top_left),
        }
    }

    /// Checks whether any side is set.
    pub fn is_empty(&self) -> bool {
        self.top.is_none()
            && self.left_top_corner.is_none()
            && self.right_top_corner.is_none()
            && self.bottom.is_none()
            && self.left_bottom_corner.is_none()
            && self.left_top_corner.is_none()
            && self.left.is_none()
            && self.right.is_none()
    }
}

impl<T: Copy> Border<T> {
    /// This function constructs a cell borders with all sides's char set to a given character.
    ///
    /// It behaives like [`Border::full`] with the same character set to each side.
    pub fn filled(c: T) -> Self {
        Self::full(c, c, c, c, c, c, c, c)
    }
}

impl<T: Copy> Border<&T> {
    /// This function constructs a cell borders with all sides's char set to a given character.
    ///
    /// It behaives like [`Border::full`] with the same character set to each side.
    pub fn copied(&self) -> Border<T> {
        Border {
            top: self.top.copied(),
            bottom: self.bottom.copied(),
            left: self.left.copied(),
            right: self.right.copied(),
            left_bottom_corner: self.left_bottom_corner.copied(),
            left_top_corner: self.left_top_corner.copied(),
            right_bottom_corner: self.right_bottom_corner.copied(),
            right_top_corner: self.right_top_corner.copied(),
        }
    }
}

impl<T: Clone> Border<&T> {
    /// This function constructs a cell borders with all sides's char set to a given character.
    ///
    /// It behaives like [`Border::full`] with the same character set to each side.
    pub fn cloned(&self) -> Border<T> {
        Border {
            top: self.top.cloned(),
            bottom: self.bottom.cloned(),
            left: self.left.cloned(),
            right: self.right.cloned(),
            left_bottom_corner: self.left_bottom_corner.cloned(),
            left_top_corner: self.left_top_corner.cloned(),
            right_bottom_corner: self.right_bottom_corner.cloned(),
            right_top_corner: self.right_top_corner.cloned(),
        }
    }
}