winget_types/locale/
description.rs

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