• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TinTeam / SN-50 / 14149942514

29 Mar 2025 10:20PM UTC coverage: 91.618% (-1.7%) from 93.269%
14149942514

Pull #5

github

web-flow
Merge 11985a483 into d5615e274
Pull Request #5: refactor: improve tinlib code

36 of 62 new or added lines in 4 files covered. (58.06%)

6 existing lines in 2 files now uncovered.

1716 of 1873 relevant lines covered (91.62%)

36926.27 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.97
/tinlib/src/graphic/font.rs
1
//! Font implementation and manipulation.
2
use std::fmt;
3
use std::slice;
4

5
use crate::common::Size;
6
use crate::common::{CommonError, Result};
7
use crate::graphic::glyph::Glyph;
8

9
/// Default number of Glyphs in a Font.
10
const NUM_GLYPHS_IN_FONT: usize = 256;
11
/// Default glyph width.
12
const GLYPH_WIDTH: usize = 16;
13
/// Default glyph height.
14
const GLYPH_HEIGHT: usize = 16;
15

16
/// A iterator over all font glyphs.
17
pub type FontGlyphIter<'iter> = slice::Iter<'iter, Glyph>;
18
/// A mutable iterator over all font glyphs.
19
pub type FontGlyphIterMut<'iter> = slice::IterMut<'iter, Glyph>;
20

21
/// A Font representation with N Glyphs.
22
#[derive(Clone)]
23
pub struct Font {
24
    /// Font's glyph size.
25
    glyph_size: Size,
26
    /// Font's glyphs.
27
    glyphs: Vec<Glyph>,
28
}
29

30
impl Font {
31
    /// Creates a new Font.
NEW
32
    pub fn new(glyph_size: Size, num_glyphs: usize) -> Self {
×
NEW
33
        Self {
×
NEW
34
            glyph_size,
×
NEW
35
            glyphs: vec![Glyph::default(); num_glyphs],
×
NEW
36
        }
×
NEW
37
    }
×
38

39
    /// Returns glyph's size.
NEW
40
    pub fn glyph_size(&self) -> Size {
×
NEW
41
        self.glyph_size
×
NEW
42
    }
×
43

44
    /// Returns the lenght.
45
    pub fn lenght(&self) -> usize {
10✔
46
        self.glyphs.len()
10✔
47
    }
10✔
48

49
    /// Returns a glyph.
50
    pub fn get_glyph(&self, index: usize) -> Result<&Glyph> {
3✔
51
        if !self.is_index_valid(index) {
3✔
52
            return Err(CommonError::new_invalid_index(index, self.lenght()));
1✔
53
        }
2✔
54

2✔
55
        Ok(&self.glyphs[index])
2✔
56
    }
3✔
57

58
    /// Returns a mutable glyph.
NEW
59
    pub fn get_glyph_mut(&mut self, index: usize) -> Result<&mut Glyph> {
×
UNCOV
60
        if !self.is_index_valid(index) {
×
UNCOV
61
            return Err(CommonError::new_invalid_index(index, self.lenght()));
×
UNCOV
62
        }
×
UNCOV
63

×
NEW
64
        Ok(&mut self.glyphs[index])
×
UNCOV
65
    }
×
66

67
    /// Sets a glyph.
68
    pub fn set_glyph(&mut self, index: usize, glyph: Glyph) -> Result<()> {
2✔
69
        if !self.is_index_valid(index) {
2✔
70
            return Err(CommonError::new_invalid_index(index, self.lenght()));
1✔
71
        }
1✔
72

1✔
73
        self.glyphs[index] = glyph;
1✔
74

1✔
75
        Ok(())
1✔
76
    }
2✔
77

78
    /// Returns an iterator over all font glyphs.
79
    pub fn iter(&self) -> FontGlyphIter {
2✔
80
        self.glyphs.iter()
2✔
81
    }
2✔
82

83
    /// Returns a mutable iterator over all font glyphs.
84
    pub fn iter_mut(&mut self) -> FontGlyphIterMut {
1✔
85
        self.glyphs.iter_mut()
1✔
86
    }
1✔
87

88
    fn is_index_valid(&self, index: usize) -> bool {
5✔
89
        index < self.lenght()
5✔
90
    }
5✔
91
}
92

93
impl Default for Font {
94
    /// Creates a Font with default empty glyphs.
95
    fn default() -> Self {
9✔
96
        Self {
9✔
97
            glyph_size: Size::new(GLYPH_WIDTH, GLYPH_HEIGHT),
9✔
98
            glyphs: vec![Glyph::default(); NUM_GLYPHS_IN_FONT],
9✔
99
        }
9✔
100
    }
9✔
101
}
102

103
impl fmt::Debug for Font {
104
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1✔
105
        let data: Vec<&Glyph> = self.glyphs.iter().collect();
1✔
106

1✔
107
        f.debug_struct("Font").field("data", &data).finish()
1✔
108
    }
1✔
109
}
110

111
#[cfg(test)]
112
mod tests {
113
    use assert_matches::assert_matches;
114

115
    use crate::common::Coord;
116
    use crate::graphic::glyph::GlyphPixel;
117

118
    use super::*;
119

120
    #[test]
121
    fn test_font_default() {
1✔
122
        let font = Font::default();
1✔
123
        assert_eq!(font.glyphs.len(), NUM_GLYPHS_IN_FONT);
1✔
124
    }
1✔
125

126
    #[test]
127
    fn test_font_len() {
1✔
128
        let font = Font::default();
1✔
129
        assert_eq!(font.lenght(), NUM_GLYPHS_IN_FONT);
1✔
130
    }
1✔
131

132
    #[test]
133
    fn test_font_get_glyph() {
1✔
134
        let font = Font::default();
1✔
135
        let glyph = Glyph::default();
1✔
136

1✔
137
        let result = font.get_glyph(0);
1✔
138
        assert!(result.is_ok());
1✔
139
        assert_eq!(result.unwrap(), &glyph);
1✔
140
    }
1✔
141

142
    #[test]
143
    fn test_font_get_glyph_invalid_index() {
1✔
144
        let font = Font::default();
1✔
145
        let index = 256usize;
1✔
146

1✔
147
        let result = font.get_glyph(index);
1✔
148
        assert!(result.is_err());
1✔
149
        assert_matches!(
1✔
150
            result.unwrap_err(),
1✔
151
            CommonError::InvalidIndex { index: i, lenght: l } if i == index && l == font.lenght()
1✔
152
        );
1✔
153
    }
1✔
154

155
    #[test]
156
    fn test_font_set_glyph() {
1✔
157
        let mut font = Font::default();
1✔
158

1✔
159
        let coord = Coord::new(0, 0);
1✔
160
        let mut new_glyph = Glyph::default();
1✔
161
        new_glyph.set_pixel(coord, GlyphPixel::Solid).unwrap();
1✔
162

1✔
163
        let result = font.set_glyph(0, new_glyph.clone());
1✔
164
        assert!(result.is_ok());
1✔
165

166
        let result = font.get_glyph(0);
1✔
167
        assert_eq!(result.unwrap(), &new_glyph);
1✔
168
    }
1✔
169

170
    #[test]
171
    fn test_font_set_glyph_invalid_index() {
1✔
172
        let mut font = Font::default();
1✔
173
        let glyph = Glyph::default();
1✔
174
        let index = 256usize;
1✔
175

1✔
176
        let result = font.set_glyph(index, glyph);
1✔
177
        assert!(result.is_err());
1✔
178
        assert_matches!(
1✔
179
            result.unwrap_err(),
1✔
180
            CommonError::InvalidIndex { index: i, lenght: l } if i == index && l == font.lenght()
1✔
181
        );
1✔
182
    }
1✔
183

184
    #[test]
185
    fn test_font_iter() {
1✔
186
        let font = Font::default();
1✔
187
        let default_glyph = Glyph::default();
1✔
188

189
        for color in font.iter() {
256✔
190
            assert_eq!(color, &default_glyph);
256✔
191
        }
192
    }
1✔
193

194
    #[test]
195
    fn test_font_iter_mut() {
1✔
196
        let mut font = Font::default();
1✔
197

1✔
198
        let coord = Coord::new(0, 0);
1✔
199
        let mut new_glyph = Glyph::default();
1✔
200
        new_glyph.set_pixel(coord, GlyphPixel::Solid).unwrap();
1✔
201

202
        for glyph in font.iter_mut() {
256✔
203
            *glyph = new_glyph.clone();
256✔
204
        }
256✔
205

206
        for glyph in font.iter() {
256✔
207
            assert_eq!(glyph, &new_glyph);
256✔
208
        }
209
    }
1✔
210

211
    #[test]
212
    fn test_font_debug() {
1✔
213
        let font = Font::default();
1✔
214
        let data: Vec<&Glyph> = font.glyphs.iter().collect();
1✔
215

1✔
216
        let expected = format!("Font {{ data: {:?} }}", data);
1✔
217
        let result = format!("{:?}", font);
1✔
218

1✔
219
        assert_eq!(result, expected);
1✔
220
    }
1✔
221
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc