mm_client_common/
pixel_scale.rs

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
// Copyright 2024 Colin Marc <hi@colinmarc.com>
//
// SPDX-License-Identifier: MIT

use mm_protocol as protocol;

use crate::validation::*;

#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Record)]
pub struct PixelScale {
    numerator: u32,
    denominator: u32,
}

impl PixelScale {
    pub const ONE: Self = Self {
        numerator: 1,
        denominator: 1,
    };

    pub fn new(numerator: u32, denominator: u32) -> Self {
        Self {
            numerator,
            denominator,
        }
    }

    pub fn is_fractional(&self) -> bool {
        (self.numerator % self.denominator) != 0
    }

    pub fn round_up(self) -> Self {
        Self {
            numerator: self.numerator.next_multiple_of(self.denominator) / self.denominator,
            denominator: 1,
        }
    }
}

impl std::fmt::Display for PixelScale {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:.1}", self.numerator as f64 / self.denominator as f64)
    }
}

impl TryFrom<protocol::PixelScale> for PixelScale {
    type Error = ValidationError;

    fn try_from(scale: protocol::PixelScale) -> Result<Self, Self::Error> {
        if scale.denominator == 0 && scale.numerator != 0 {
            Ok(Self::ONE)
        } else if scale.denominator == 0 || scale.numerator == 0 {
            Err(ValidationError::Required("denominator".to_string()))
        } else {
            Ok(Self {
                numerator: scale.numerator,
                denominator: scale.denominator,
            })
        }
    }
}

impl From<PixelScale> for protocol::PixelScale {
    fn from(scale: PixelScale) -> Self {
        Self {
            numerator: scale.numerator,
            denominator: scale.denominator,
        }
    }
}