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