1use std::convert::Infallible;
20
21use xml::name::OwnedName;
22
23use crate::models::bom::SpecVersion;
24
25#[derive(Debug, thiserror::Error)]
26#[non_exhaustive]
27pub enum BomError {
28 #[error("Failed to serialize BOM to JSON: {0}")]
29 JsonSerializationError(#[from] serde_json::Error),
30
31 #[error("Failed to serialize BOM to XML: {0}")]
32 XmlSerializationError(String),
33
34 #[error("Failed to serialize BOM with version {0:?}: {1}")]
35 BomSerializationError(SpecVersion, String),
36
37 #[error("Unsupported Spec Version '{0}'")]
38 UnsupportedSpecVersion(String),
39}
40
41impl From<Infallible> for BomError {
44 fn from(err: Infallible) -> Self {
45 match err {}
46 }
47}
48
49#[derive(Debug, thiserror::Error)]
50#[non_exhaustive]
51pub enum JsonWriteError {
52 #[error("Failed to serialize JSON: {error}")]
53 JsonElementWriteError {
54 #[from]
55 error: serde_json::Error,
56 },
57 #[error("Failed to convert Bom: {error}")]
58 BomError {
59 #[from]
60 error: BomError,
61 },
62}
63
64#[derive(Debug, thiserror::Error)]
65#[non_exhaustive]
66pub enum XmlWriteError {
67 #[error("Failed to serialize XML while writing {element}: {error}")]
68 XmlElementWriteError {
69 #[source]
70 error: xml::writer::Error,
71 element: String,
72 },
73 #[error("Failed to convert Bom: {error}")]
74 BomError {
75 #[from]
76 error: BomError,
77 },
78}
79
80#[derive(Debug, thiserror::Error)]
81#[non_exhaustive]
82pub enum JsonReadError {
83 #[error("Failed to deserialize JSON: {error}")]
84 JsonElementReadError {
85 #[from]
86 error: serde_json::Error,
87 },
88 #[error("Invalid input format found: {error}")]
89 BomError {
90 #[from]
91 error: BomError,
92 },
93}
94
95#[derive(Debug, thiserror::Error)]
96#[non_exhaustive]
97pub enum XmlReadError {
98 #[error("Failed to deserialize XML while reading {element}: {error}")]
99 ElementReadError {
100 #[source]
101 error: xml::reader::Error,
102 element: String,
103 },
104 #[error("Got unexpected XML element when reading {element}: {error}")]
105 UnexpectedElementReadError { error: String, element: String },
106
107 #[error("Ended element {element} without data for required field {required_field}")]
108 RequiredDataMissing {
109 required_field: String,
110 element: String,
111 },
112
113 #[error("Required attribute {attribute} not found in element {element}")]
114 RequiredAttributeMissing { attribute: String, element: String },
115
116 #[error("Could not parse {value} as {data_type} on {element}")]
117 InvalidParseError {
118 value: String,
119 data_type: String,
120 element: String,
121 },
122
123 #[error(
124 "Expected document to be in the form {expected_namespace}, but received {}", .actual_namespace.as_ref().unwrap_or(&"no CycloneDX namespace".to_string())
125 )]
126 InvalidNamespaceError {
127 expected_namespace: String,
128 actual_namespace: Option<String>,
129 },
130}
131
132impl XmlReadError {
133 pub fn required_data_missing(required_field: &str, element: &OwnedName) -> Self {
134 Self::RequiredDataMissing {
135 required_field: required_field.to_string(),
136 element: element.local_name.to_string(),
137 }
138 }
139}