winget_types/locale/
copyright.rs

1use core::{fmt, str::FromStr};
2
3use compact_str::CompactString;
4use thiserror::Error;
5
6#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8#[cfg_attr(feature = "serde", serde(try_from = "CompactString"))]
9#[repr(transparent)]
10pub struct Copyright(CompactString);
11
12#[derive(Debug, Error, Eq, PartialEq)]
13pub enum CopyrightError {
14    #[error(
15        "Copyright must have at least {} characters but has {_0}",
16        Copyright::MIN_CHAR_LENGTH
17    )]
18    TooShort(usize),
19    #[error(
20        "Copyright must not have more than {} characters but has {_0}",
21        Copyright::MAX_CHAR_LENGTH
22    )]
23    TooLong(usize),
24}
25
26impl Copyright {
27    pub const MIN_CHAR_LENGTH: usize = 3;
28    pub const MAX_CHAR_LENGTH: usize = 512;
29
30    /// Creates a new `Copyright` from any type that implements `AsRef<str>` and
31    /// `Into<CompactString>`.
32    ///
33    /// # Errors
34    ///
35    /// Returns an `Err` if the copyright is less than 3 characters long or more than 512 characters
36    /// long.
37    ///
38    /// # Examples
39    ///
40    /// ```
41    /// use winget_types::locale::Copyright;
42    /// # use winget_types::locale::CopyrightError;
43    ///
44    /// # fn main() -> Result<(), CopyrightError>  {
45    /// let copyright = Copyright::new("Copyright © Company")?;
46    ///
47    /// assert_eq!(copyright.as_str(), "Copyright © Company");
48    /// # Ok(())
49    /// # }
50    /// ```
51    pub fn new<T: AsRef<str> + Into<CompactString>>(copyright: T) -> Result<Self, CopyrightError> {
52        match copyright.as_ref().chars().count() {
53            count if count < Self::MIN_CHAR_LENGTH => Err(CopyrightError::TooShort(count)),
54            count if count > Self::MAX_CHAR_LENGTH => Err(CopyrightError::TooLong(count)),
55            _ => Ok(Self(copyright.into())),
56        }
57    }
58
59    /// Creates a new `Copyright` from any type that implements `Into<CompactString>` without
60    /// checking its validity.
61    ///
62    /// # Safety
63    ///
64    /// The license must not be less than 3 characters long or more than 512 characters long.
65    #[must_use]
66    #[inline]
67    pub unsafe fn new_unchecked<T: Into<CompactString>>(copyright: T) -> Self {
68        Self(copyright.into())
69    }
70
71    /// Extracts a string slice containing the entire `Copyright`.
72    #[must_use]
73    #[inline]
74    pub fn as_str(&self) -> &str {
75        self.0.as_str()
76    }
77}
78
79impl AsRef<str> for Copyright {
80    #[inline]
81    fn as_ref(&self) -> &str {
82        self.as_str()
83    }
84}
85
86impl fmt::Display for Copyright {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        self.0.fmt(f)
89    }
90}
91
92impl FromStr for Copyright {
93    type Err = CopyrightError;
94
95    #[inline]
96    fn from_str(s: &str) -> Result<Self, Self::Err> {
97        Self::new(s)
98    }
99}
100
101impl TryFrom<CompactString> for Copyright {
102    type Error = CopyrightError;
103
104    #[inline]
105    fn try_from(value: CompactString) -> Result<Self, Self::Error> {
106        Self::new(value)
107    }
108}