cyclonedx_bom/external_models/
normalized_string.rs1use crate::validation::ValidationError;
20use std::fmt::Display;
21use std::ops::Deref;
22
23#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
27pub struct NormalizedString(pub(crate) String);
28
29impl NormalizedString {
30 pub fn new(value: &str) -> Self {
38 let value = value.replace("\r\n", " ").replace(['\r', '\n', '\t'], " ");
39 NormalizedString(value)
40 }
41
42 pub(crate) fn new_unchecked(value: String) -> Self {
44 NormalizedString(value)
45 }
46}
47
48impl From<&str> for NormalizedString {
49 fn from(input: &str) -> Self {
50 NormalizedString::new(input)
51 }
52}
53
54impl From<NormalizedString> for String {
55 fn from(value: NormalizedString) -> Self {
56 value.0
57 }
58}
59
60impl Deref for NormalizedString {
61 type Target = str;
62
63 fn deref(&self) -> &Self::Target {
64 &self.0
65 }
66}
67
68impl AsRef<NormalizedString> for NormalizedString {
69 fn as_ref(&self) -> &NormalizedString {
70 self
71 }
72}
73
74impl AsRef<str> for NormalizedString {
75 fn as_ref(&self) -> &str {
76 &self.0
77 }
78}
79
80impl Display for NormalizedString {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 write!(f, "{}", self.0)
83 }
84}
85
86pub fn validate_normalized_string(
88 normalized_string: &NormalizedString,
89) -> Result<(), ValidationError> {
90 if normalized_string.contains("\r\n")
91 || normalized_string.contains('\r')
92 || normalized_string.contains('\n')
93 || normalized_string.contains('\t')
94 {
95 return Err(ValidationError::new(
96 "NormalizedString contains invalid characters \\r \\n \\t or \\r\\n",
97 ));
98 }
99
100 Ok(())
101}
102
103#[cfg(test)]
104mod test {
105 use super::*;
106 use pretty_assertions::assert_eq;
107
108 #[test]
109 fn it_should_normalize_strings() {
110 assert_eq!(
111 NormalizedString("no_whitespace".to_string()),
112 NormalizedString::new("no_whitespace")
113 );
114 assert_eq!(
115 NormalizedString("spaces and tabs".to_string()),
116 NormalizedString::new("spaces and\ttabs")
117 );
118 assert_eq!(
119 NormalizedString("carriage returns and linefeeds".to_string()),
120 NormalizedString::new("carriage\r\nreturns\rand\nlinefeeds")
121 );
122 }
123
124 #[test]
125 fn it_should_pass_validation() {
126 assert!(validate_normalized_string(&NormalizedString("no_whitespace".to_string())).is_ok());
127 }
128
129 #[test]
130 fn it_should_fail_validation() {
131 let result = validate_normalized_string(&NormalizedString("spaces and\ttabs".to_string()));
132
133 assert_eq!(
134 result,
135 Err(ValidationError::new(
136 "NormalizedString contains invalid characters \\r \\n \\t or \\r\\n",
137 ))
138 );
139 }
140}