Skip to main content

qrcode_core/
version.rs

1//! Compile-time QR version markers.
2
3use crate::types::Version;
4
5/// A compile-time checked normal QR version.
6///
7/// `N` must be in the normal QR version range `1..=40`. The range is checked
8/// when [`ConstVersion::new`] or [`ConstVersion::VALUE`] is evaluated, so an
9/// invalid fixed-version path fails at compile time instead of reaching the
10/// encoder.
11///
12/// ```
13/// use qrcode_core::{ConstVersion, Version};
14///
15/// const V5: Version = ConstVersion::<5>::VALUE;
16/// assert_eq!(V5, Version::Normal(5));
17/// ```
18///
19/// ```compile_fail
20/// use qrcode_core::ConstVersion;
21///
22/// const INVALID: qrcode_core::Version = ConstVersion::<41>::VALUE;
23/// ```
24#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
25pub struct ConstVersion<const N: i16>;
26
27impl<const N: i16> ConstVersion<N> {
28    /// The dynamic [`Version`] represented by this compile-time marker.
29    pub const VALUE: Version = {
30        assert!(N >= 1 && N <= 40, "normal QR version must be in 1..=40");
31        Version::Normal(N)
32    };
33
34    /// Creates a compile-time checked fixed-version marker.
35    pub const fn new() -> Self {
36        let _ = Self::VALUE;
37        Self
38    }
39
40    /// Returns the dynamic [`Version`] value for this marker.
41    pub const fn version(self) -> Version {
42        Self::VALUE
43    }
44}
45
46/// A type-level fixed QR version.
47pub trait StaticVersion: Copy {
48    /// The dynamic [`Version`] represented by this type.
49    const VERSION: Version;
50}
51
52impl<const N: i16> StaticVersion for ConstVersion<N> {
53    const VERSION: Version = ConstVersion::<N>::VALUE;
54}
55
56#[cfg(test)]
57mod tests {
58    use super::{ConstVersion, StaticVersion};
59    use crate::types::Version;
60
61    #[test]
62    fn const_version_exposes_dynamic_normal_version() {
63        const V5: Version = ConstVersion::<5>::VALUE;
64
65        assert_eq!(V5, Version::Normal(5));
66        assert_eq!(ConstVersion::<5>::new().version(), Version::Normal(5));
67        assert_eq!(<ConstVersion<5> as StaticVersion>::VERSION, Version::Normal(5));
68    }
69}