Skip to main content

winprint_ext/ticket/
media_size_tuple.rs

1use std::fmt;
2
3#[derive(Clone, Copy, PartialEq, Eq, Hash)]
4/// Represents a media size tuple.
5pub struct MediaSizeTuple(u32, u32);
6impl MediaSizeTuple {
7    /// Create a new media size tuple using width and height in micron.
8    pub const fn micron(width: u32, height: u32) -> Self {
9        MediaSizeTuple(width, height)
10    }
11    /// Create a new media size tuple using width and height in millimeter.
12    pub const fn mm(width: u32, height: u32) -> Self {
13        MediaSizeTuple(width * 1000, height * 1000)
14    }
15    /// Get the width in micron.
16    pub const fn width_in_micron(&self) -> u32 {
17        self.0
18    }
19    /// Get the height in micron.
20    pub const fn height_in_micron(&self) -> u32 {
21        self.1
22    }
23    /// Set the width in micron.
24    pub fn set_width_in_micron(&mut self, width: u32) {
25        self.0 = width;
26    }
27    /// Set the height in micron.
28    pub fn set_height_in_micron(&mut self, height: u32) {
29        self.1 = height;
30    }
31    /// Determine if the media is a roll media.
32    pub fn is_roll(&self) -> bool {
33        // for roll media, either width or height is 0
34        self.0 == 0 || self.1 == 0
35    }
36}
37
38impl fmt::Debug for MediaSizeTuple {
39    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40        write!(
41            f,
42            "MediaSizeTuple({}.{:0>4} cm × {}.{:0>4} cm)",
43            self.0 / 10000,
44            self.0 % 10000,
45            self.1 / 10000,
46            self.1 % 10000
47        )
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn test_getter_and_setter() {
57        let mut size = MediaSizeTuple::mm(210, 297);
58        assert_eq!(size.width_in_micron(), 210000);
59        assert_eq!(size.height_in_micron(), 297000);
60        size.set_width_in_micron(297000);
61        size.set_height_in_micron(210000);
62        assert_eq!(size.width_in_micron(), 297000);
63        assert_eq!(size.height_in_micron(), 210000);
64    }
65
66    #[test]
67    fn test_debug_fmt() {
68        assert_eq!(
69            format!("{:?}", MediaSizeTuple::mm(210, 297)),
70            "MediaSizeTuple(21.0000 cm × 29.7000 cm)"
71        );
72        assert_eq!(
73            format!("{:?}", MediaSizeTuple::micron(210001, 297001)),
74            "MediaSizeTuple(21.0001 cm × 29.7001 cm)"
75        );
76    }
77
78    #[test]
79    fn test_eq() {
80        assert_eq!(
81            MediaSizeTuple::micron(210000, 297000),
82            MediaSizeTuple::mm(210, 297)
83        );
84    }
85
86    #[test]
87    fn test_clone() {
88        let size = MediaSizeTuple::mm(210, 297);
89        assert_eq!(size, size.clone());
90    }
91
92    #[test]
93    fn test_hash() {
94        use std::collections::hash_map::DefaultHasher;
95        use std::hash::{Hash, Hasher};
96        let hash1 = {
97            let mut hasher = DefaultHasher::new();
98            MediaSizeTuple::mm(210, 297).hash(&mut hasher);
99            hasher.finish()
100        };
101        let hash2 = {
102            let mut hasher = DefaultHasher::new();
103            MediaSizeTuple::micron(210000, 297000).hash(&mut hasher);
104            hasher.finish()
105        };
106        assert_eq!(hash1, hash2);
107    }
108
109    #[test]
110    fn test_is_roll() {
111        assert_eq!(MediaSizeTuple::mm(210, 297).is_roll(), false);
112        assert!(MediaSizeTuple::mm(210, 0).is_roll());
113        assert!(MediaSizeTuple::mm(0, 297).is_roll());
114    }
115}