twilight_validate/
sticker.rs1use std::{
6 error::Error,
7 fmt::{Display, Formatter, Result as FmtResult},
8};
9
10pub const STICKER_DESCRIPTION_LENGTH_MAX: usize = 200;
12
13pub const STICKER_DESCRIPTION_LENGTH_MIN: usize = 2;
15
16pub const STICKER_NAME_LENGTH_MAX: usize = 30;
18
19pub const STICKER_NAME_LENGTH_MIN: usize = 2;
21
22pub const STICKER_TAGS_LENGTH_MAX: usize = 200;
24
25pub const STICKER_TAGS_LENGTH_MIN: usize = 2;
27
28#[derive(Debug)]
30pub struct StickerValidationError {
31 kind: StickerValidationErrorType,
33}
34
35impl StickerValidationError {
36 #[must_use = "retrieving the type has no effect if left unused"]
38 pub const fn kind(&self) -> &StickerValidationErrorType {
39 &self.kind
40 }
41
42 #[allow(clippy::unused_self)]
44 #[must_use = "consuming the error and retrieving the source has no effect if left unused"]
45 pub fn into_source(self) -> Option<Box<dyn Error + Send + Sync>> {
46 None
47 }
48
49 #[must_use = "consuming the error into its parts has no effect if left unused"]
51 pub fn into_parts(
52 self,
53 ) -> (
54 StickerValidationErrorType,
55 Option<Box<dyn Error + Send + Sync>>,
56 ) {
57 (self.kind, None)
58 }
59}
60
61impl Display for StickerValidationError {
62 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
63 match self.kind {
64 StickerValidationErrorType::DescriptionInvalid => {
65 f.write_str("sticker's description is invalid")
66 }
67 StickerValidationErrorType::NameInvalid => f.write_str("sticker's name is invalid"),
68 StickerValidationErrorType::TagsInvalid => f.write_str("sticker's tags are invalid"),
69 }
70 }
71}
72
73impl Error for StickerValidationError {}
74
75#[derive(Debug)]
77pub enum StickerValidationErrorType {
78 DescriptionInvalid,
80 NameInvalid,
82 TagsInvalid,
84}
85
86pub fn description(value: impl AsRef<str>) -> Result<(), StickerValidationError> {
99 let len = value.as_ref().chars().count();
100
101 if (STICKER_DESCRIPTION_LENGTH_MIN..=STICKER_DESCRIPTION_LENGTH_MAX).contains(&len) {
102 Ok(())
103 } else {
104 Err(StickerValidationError {
105 kind: StickerValidationErrorType::DescriptionInvalid,
106 })
107 }
108}
109
110pub fn name(value: impl AsRef<str>) -> Result<(), StickerValidationError> {
122 let len = value.as_ref().chars().count();
123
124 if (STICKER_NAME_LENGTH_MIN..=STICKER_NAME_LENGTH_MAX).contains(&len) {
125 Ok(())
126 } else {
127 Err(StickerValidationError {
128 kind: StickerValidationErrorType::NameInvalid,
129 })
130 }
131}
132
133pub fn tags(value: impl AsRef<str>) -> Result<(), StickerValidationError> {
145 let len = value.as_ref().chars().count();
146
147 if (STICKER_TAGS_LENGTH_MIN..=STICKER_TAGS_LENGTH_MAX).contains(&len) {
148 Ok(())
149 } else {
150 Err(StickerValidationError {
151 kind: StickerValidationErrorType::TagsInvalid,
152 })
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159
160 #[test]
161 fn description_length() {
162 assert!(description("aa").is_ok());
163 assert!(description("a".repeat(200)).is_ok());
164
165 assert!(description("a").is_err());
166 assert!(description("a".repeat(201)).is_err());
167 }
168
169 #[test]
170 fn name_length() {
171 assert!(name("aa").is_ok());
172 assert!(name("a".repeat(30)).is_ok());
173
174 assert!(name("a").is_err());
175 assert!(name("a".repeat(31)).is_err());
176 }
177
178 #[test]
179 fn tags_length() {
180 assert!(tags("aa").is_ok());
181 assert!(tags("a".repeat(200)).is_ok());
182
183 assert!(tags("a").is_err());
184 assert!(tags("a".repeat(201)).is_err());
185 }
186}