kellnr_common/
original_name.rs1use std::convert::TryFrom;
2use std::fmt;
3use std::ops::Deref;
4
5use regex::Regex;
6use sea_orm::Value;
7use thiserror::Error;
8use utoipa::ToSchema;
9
10use crate::normalized_name::NormalizedName;
11
12#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone, Hash, ToSchema)]
13#[schema(value_type = String)]
14pub struct OriginalName(String);
15
16#[derive(Debug, PartialEq, Eq, Error)]
17pub enum NameError {
18 #[error("Invalid character in name")]
19 InvalidCharacter,
20 #[error("Invalid length for name")]
21 InvalidLength,
22}
23
24impl OriginalName {
25 pub fn to_normalized(&self) -> NormalizedName {
26 NormalizedName::from(self)
27 }
28 pub fn from_unchecked(name: String) -> Self {
29 Self(name)
30 }
31 pub fn into_inner(self) -> String {
32 self.0
33 }
34}
35
36impl TryFrom<String> for OriginalName {
37 type Error = NameError;
38
39 fn try_from(package_name: String) -> Result<Self, Self::Error> {
40 let re = Regex::new(r"^[a-zA-Z][a-zA-Z0-9-_]*$").unwrap();
41
42 if !re.is_match(&package_name) {
43 Err(NameError::InvalidCharacter)
44 } else if package_name.len() > 64 {
45 Err(NameError::InvalidLength)
46 } else {
47 Ok(OriginalName(package_name))
48 }
49 }
50}
51
52impl From<&OriginalName> for String {
53 fn from(name: &OriginalName) -> Self {
54 name.to_string()
55 }
56}
57
58impl From<OriginalName> for String {
59 fn from(name: OriginalName) -> Self {
60 name.to_string()
61 }
62}
63
64impl From<OriginalName> for Value {
65 fn from(value: OriginalName) -> Self {
66 Value::String(Some(value.0))
67 }
68}
69
70impl From<&OriginalName> for Value {
71 fn from(value: &OriginalName) -> Self {
72 Value::String(Some(value.0.clone()))
73 }
74}
75
76impl TryFrom<&String> for OriginalName {
77 type Error = NameError;
78
79 fn try_from(package_name: &String) -> Result<Self, Self::Error> {
80 OriginalName::try_from(package_name.clone())
81 }
82}
83
84impl TryFrom<&str> for OriginalName {
85 type Error = NameError;
86
87 fn try_from(package_name: &str) -> Result<Self, Self::Error> {
88 OriginalName::try_from(package_name.to_string())
89 }
90}
91
92impl Deref for OriginalName {
93 type Target = String;
94
95 fn deref(&self) -> &Self::Target {
96 &self.0
97 }
98}
99
100impl fmt::Display for OriginalName {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 write!(f, "{}", self.0)
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn valid_package_names() {
112 assert_eq!(
113 OriginalName::try_from("test-lib").unwrap(),
114 OriginalName("test-lib".to_string())
115 );
116 assert_eq!(
117 OriginalName::try_from("Test_lib").unwrap(),
118 OriginalName("Test_lib".to_string())
119 );
120 assert_eq!(
121 OriginalName::try_from("test_lib_foo").unwrap(),
122 OriginalName("test_lib_foo".to_string())
123 );
124 assert_eq!(
125 OriginalName::try_from("test-lIB-foo").unwrap(),
126 OriginalName("test-lIB-foo".to_string())
127 );
128 assert_eq!(
129 OriginalName::try_from("test12_14f").unwrap(),
130 OriginalName("test12_14f".to_string())
131 );
132 assert_eq!(
133 OriginalName::try_from("tEs2-23_1f").unwrap(),
134 OriginalName("tEs2-23_1f".to_string())
135 );
136 assert_eq!(
137 OriginalName::try_from("testlib").unwrap(),
138 OriginalName("testlib".to_string())
139 );
140 assert_eq!(
141 OriginalName::try_from("Testlib23").unwrap(),
142 OriginalName("Testlib23".to_string())
143 );
144 }
145
146 #[test]
147 fn invalid_characters_in_package_name() {
148 assert_eq!(
149 OriginalName::try_from("_test").unwrap_err(),
150 NameError::InvalidCharacter
151 );
152 assert_eq!(
153 OriginalName::try_from("44Test").unwrap_err(),
154 NameError::InvalidCharacter
155 );
156 assert_eq!(
157 OriginalName::try_from("-Av").unwrap_err(),
158 NameError::InvalidCharacter
159 );
160 assert_eq!(
161 OriginalName::try_from("testÄ").unwrap_err(),
162 NameError::InvalidCharacter
163 );
164 assert_eq!(
165 OriginalName::try_from("test?").unwrap_err(),
166 NameError::InvalidCharacter
167 );
168 assert_eq!(
169 OriginalName::try_from(".45A").unwrap_err(),
170 NameError::InvalidCharacter
171 );
172 assert_eq!(
173 OriginalName::try_from("").unwrap_err(),
174 NameError::InvalidCharacter
175 );
176 }
177
178 #[test]
179 fn too_long_package_name() {
180 assert_eq!(
181 OriginalName::try_from(
182 "zbsfrofdgxekytxrporaocoieaviehlvjrroockxufdkzgtxudkmdkentyyhkmtpx"
183 )
184 .unwrap_err(),
185 NameError::InvalidLength
186 );
187 }
188}