Skip to content

Commit 7371323

Browse files
committed
Add function to add index to ValidationContext
* refactor `ValidationResult::Failed` to use `failure` function for a single validation event * add helper `with_index` to `ValidationContext` to store an associated index * refactor `FailureReason` in tests Signed-off-by: Sebastian Ziebell <[email protected]>
1 parent 135d279 commit 7371323

20 files changed

+172
-316
lines changed

cyclonedx-bom/src/external_models/date_time.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::convert::TryFrom;
2121
use thiserror::Error;
2222
use time::{format_description::well_known::Iso8601, OffsetDateTime};
2323

24-
use crate::validation::{FailureReason, Validate, ValidationContext, ValidationResult};
24+
use crate::validation::{Validate, ValidationContext, ValidationResult};
2525

2626
/// For the purposes of CycloneDX SBOM documents, `DateTime` is a ISO8601 formatted timestamp
2727
///
@@ -68,12 +68,7 @@ impl Validate for DateTime {
6868
fn validate_with_context(&self, context: ValidationContext) -> ValidationResult {
6969
match OffsetDateTime::parse(&self.0.to_string(), &Iso8601::DEFAULT) {
7070
Ok(_) => ValidationResult::Passed,
71-
Err(_) => ValidationResult::Failed {
72-
reasons: vec![FailureReason {
73-
message: "DateTime does not conform to ISO 8601".to_string(),
74-
context,
75-
}],
76-
},
71+
Err(_) => ValidationResult::failure("DateTime does not conform to ISO 8601", context),
7772
}
7873
}
7974
}
@@ -96,7 +91,6 @@ pub enum DateTimeError {
9691
#[cfg(test)]
9792
mod test {
9893
use super::*;
99-
use crate::validation::FailureReason;
10094
use pretty_assertions::assert_eq;
10195

10296
#[test]
@@ -112,12 +106,10 @@ mod test {
112106

113107
assert_eq!(
114108
validation_result,
115-
ValidationResult::Failed {
116-
reasons: vec![FailureReason {
117-
message: "DateTime does not conform to ISO 8601".to_string(),
118-
context: ValidationContext::default()
119-
}]
120-
}
109+
ValidationResult::failure(
110+
"DateTime does not conform to ISO 8601",
111+
ValidationContext::default()
112+
)
121113
)
122114
}
123115
}

cyclonedx-bom/src/external_models/normalized_string.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ impl Validate for NormalizedString {
8585
#[cfg(test)]
8686
mod test {
8787
use super::*;
88-
use crate::validation::FailureReason;
8988
use pretty_assertions::assert_eq;
9089

9190
#[test]
@@ -117,13 +116,10 @@ mod test {
117116

118117
assert_eq!(
119118
validation_result,
120-
ValidationResult::Failed {
121-
reasons: vec![FailureReason {
122-
message: "NormalizedString contains invalid characters \\r \\n \\t or \\r\\n"
123-
.to_string(),
124-
context: ValidationContext::default()
125-
}]
126-
}
119+
ValidationResult::failure(
120+
"NormalizedString contains invalid characters \\r \\n \\t or \\r\\n",
121+
ValidationContext::default()
122+
)
127123
);
128124
}
129125
}

cyclonedx-bom/src/external_models/spdx.rs

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::convert::TryFrom;
2121
use spdx::{Expression, ParseMode};
2222
use thiserror::Error;
2323

24-
use crate::validation::{FailureReason, Validate, ValidationResult};
24+
use crate::validation::{Validate, ValidationResult};
2525

2626
/// An identifier for a single, specific license
2727
///
@@ -87,12 +87,7 @@ impl Validate for SpdxIdentifier {
8787
) -> ValidationResult {
8888
match Self::try_from(self.0.clone()) {
8989
Ok(_) => ValidationResult::Passed,
90-
Err(_) => ValidationResult::Failed {
91-
reasons: vec![FailureReason {
92-
message: "SPDX identifier is not valid".to_string(),
93-
context,
94-
}],
95-
},
90+
Err(_) => ValidationResult::failure("SPDX identifier is not valid", context),
9691
}
9792
}
9893
}
@@ -187,12 +182,7 @@ impl Validate for SpdxExpression {
187182
) -> ValidationResult {
188183
match SpdxExpression::try_from(self.0.clone()) {
189184
Ok(_) => ValidationResult::Passed,
190-
Err(_) => ValidationResult::Failed {
191-
reasons: vec![FailureReason {
192-
message: "SPDX expression is not valid".to_string(),
193-
context,
194-
}],
195-
},
185+
Err(_) => ValidationResult::failure("SPDX expression is not valid", context),
196186
}
197187
}
198188
}
@@ -208,7 +198,7 @@ pub enum SpdxExpressionError {
208198

209199
#[cfg(test)]
210200
mod test {
211-
use crate::validation::{FailureReason, ValidationContext, ValidationResult};
201+
use crate::validation::{ValidationContext, ValidationResult};
212202

213203
use super::*;
214204
use pretty_assertions::assert_eq;
@@ -268,12 +258,7 @@ mod test {
268258

269259
assert_eq!(
270260
validation_result,
271-
ValidationResult::Failed {
272-
reasons: vec![FailureReason {
273-
message: "SPDX identifier is not valid".to_string(),
274-
context: ValidationContext::default()
275-
}]
276-
}
261+
ValidationResult::failure("SPDX identifier is not valid", ValidationContext::default()),
277262
);
278263
}
279264

@@ -314,12 +299,7 @@ mod test {
314299

315300
assert_eq!(
316301
validation_result,
317-
ValidationResult::Failed {
318-
reasons: vec![FailureReason {
319-
message: "SPDX expression is not valid".to_string(),
320-
context: ValidationContext::default()
321-
}]
322-
}
302+
ValidationResult::failure("SPDX expression is not valid", ValidationContext::default())
323303
);
324304
}
325305
}

cyclonedx-bom/src/external_models/uri.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ pub enum UriError {
105105
mod test {
106106
use pretty_assertions::assert_eq;
107107

108-
use crate::validation::FailureReason;
109-
110108
use super::*;
111109

112110
#[test]
@@ -122,13 +120,10 @@ mod test {
122120

123121
assert_eq!(
124122
validation_result,
125-
ValidationResult::Failed {
126-
reasons: vec![FailureReason {
127-
message: "Purl does not conform to Package URL spec: missing scheme"
128-
.to_string(),
129-
context: ValidationContext::default()
130-
}]
131-
}
123+
ValidationResult::failure(
124+
"Purl does not conform to Package URL spec: missing scheme",
125+
ValidationContext::default()
126+
),
132127
);
133128
}
134129

@@ -145,12 +140,10 @@ mod test {
145140

146141
assert_eq!(
147142
validation_result,
148-
ValidationResult::Failed {
149-
reasons: vec![FailureReason {
150-
message: "Uri does not conform to RFC 3986".to_string(),
151-
context: ValidationContext::default()
152-
}]
153-
}
143+
ValidationResult::failure(
144+
"Uri does not conform to RFC 3986",
145+
ValidationContext::default()
146+
)
154147
);
155148
}
156149
}

cyclonedx-bom/src/models/advisory.rs

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*/
1818

1919
use crate::external_models::{normalized_string::NormalizedString, uri::Uri};
20-
use crate::validation::{Validate, ValidationContext, ValidationPathComponent, ValidationResult};
20+
use crate::validation::{Validate, ValidationContext, ValidationResult};
2121

2222
/// Represents an advisory, a notification of a threat to a component, service, or system.
2323
///
@@ -71,7 +71,7 @@ impl Validate for Advisories {
7171
let mut results: Vec<ValidationResult> = vec![];
7272

7373
for (index, advisory) in self.0.iter().enumerate() {
74-
let context = context.extend_context(vec![ValidationPathComponent::Array { index }]);
74+
let context = context.with_index(index);
7575
results.push(advisory.validate_with_context(context));
7676
}
7777

@@ -114,28 +114,18 @@ mod test {
114114
validation_result,
115115
ValidationResult::Failed {
116116
reasons: vec![
117-
FailureReason {
118-
message:
119-
"NormalizedString contains invalid characters \\r \\n \\t or \\r\\n"
120-
.to_string(),
121-
context: ValidationContext(vec![
122-
ValidationPathComponent::Array { index: 0 },
123-
ValidationPathComponent::Struct {
124-
struct_name: "Advisory".to_string(),
125-
field_name: "title".to_string()
126-
},
127-
])
128-
},
129-
FailureReason {
130-
message: "Uri does not conform to RFC 3986".to_string(),
131-
context: ValidationContext(vec![
132-
ValidationPathComponent::Array { index: 0 },
133-
ValidationPathComponent::Struct {
134-
struct_name: "Advisory".to_string(),
135-
field_name: "url".to_string()
136-
}
137-
])
138-
},
117+
FailureReason::new(
118+
"NormalizedString contains invalid characters \\r \\n \\t or \\r\\n",
119+
ValidationContext::new()
120+
.with_index(0)
121+
.with_struct("Advisory", "title")
122+
),
123+
FailureReason::new(
124+
"Uri does not conform to RFC 3986",
125+
ValidationContext::new()
126+
.with_index(0)
127+
.with_struct("Advisory", "url")
128+
)
139129
]
140130
}
141131
);

cyclonedx-bom/src/models/attached_text.rs

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use base64::{engine::general_purpose::STANDARD, Engine};
2020

2121
use crate::{
2222
external_models::normalized_string::NormalizedString,
23-
validation::{FailureReason, Validate, ValidationContext, ValidationResult},
23+
validation::{Validate, ValidationContext, ValidationResult},
2424
};
2525

2626
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -60,12 +60,10 @@ impl Validate for AttachedText {
6060
(Encoding::Base64, Err(_)) => {
6161
let context = context.with_struct("AttachedText", "content");
6262

63-
results.push(ValidationResult::Failed {
64-
reasons: vec![FailureReason {
65-
message: "Content is not Base64 encoded".to_string(),
66-
context,
67-
}],
68-
})
63+
results.push(ValidationResult::failure(
64+
"Content is not Base64 encoded",
65+
context,
66+
))
6967
}
7068
(Encoding::UnknownEncoding(_), _) => {
7169
let context = context.with_struct("AttachedText", "encoding");
@@ -109,20 +107,15 @@ impl Encoding {
109107
impl Validate for Encoding {
110108
fn validate_with_context(&self, context: ValidationContext) -> ValidationResult {
111109
match self {
112-
Encoding::UnknownEncoding(_) => ValidationResult::Failed {
113-
reasons: vec![FailureReason {
114-
message: "Unknown encoding".to_string(),
115-
context,
116-
}],
117-
},
110+
Encoding::UnknownEncoding(_) => ValidationResult::failure("Unknown encoding", context),
118111
_ => ValidationResult::Passed,
119112
}
120113
}
121114
}
122115

123116
#[cfg(test)]
124117
mod test {
125-
use crate::models::attached_text::Encoding;
118+
use crate::{models::attached_text::Encoding, validation::FailureReason};
126119

127120
use super::*;
128121
use pretty_assertions::assert_eq;
@@ -168,17 +161,14 @@ mod test {
168161
validation_result,
169162
ValidationResult::Failed {
170163
reasons: vec![
171-
FailureReason {
172-
message:
173-
"NormalizedString contains invalid characters \\r \\n \\t or \\r\\n"
174-
.to_string(),
175-
context: ValidationContext::new()
176-
.with_struct("AttachedText", "content_type")
177-
},
178-
FailureReason {
179-
message: "Content is not Base64 encoded".to_string(),
180-
context: ValidationContext::new().with_struct("AttachedText", "content")
181-
}
164+
FailureReason::new(
165+
"NormalizedString contains invalid characters \\r \\n \\t or \\r\\n",
166+
ValidationContext::new().with_struct("AttachedText", "content_type")
167+
),
168+
FailureReason::new(
169+
"Content is not Base64 encoded",
170+
ValidationContext::new().with_struct("AttachedText", "content")
171+
)
182172
]
183173
}
184174
);

0 commit comments

Comments
 (0)