1use std::error::Error;
2use std::fmt;
3
4#[derive(Debug, Clone)]
6pub enum VersioningError {
7 VersionOutsideEnum { target: String },
9 DuplicateVersionEnum { first: String, second: String },
11 EmptyVersionEnum { ident: String },
13 DuplicateVersionValue {
15 value: String,
16 first: String,
17 second: String,
18 },
19 MissingVersionEnum { annotation: String, decl: String },
21 MalformedVersionReference { annotation: String, decl: String },
23 MalformedVersionMarker { decl: String },
25 MalformedVersionParameter { decl: String, reason: String },
27 DuplicateVersionParameter { decl: String },
29 UnknownVersionReference {
31 annotation: String,
32 decl: String,
33 reference: String,
34 declared: String,
35 },
36 UnsupportedVersionAnnotation { name: String, decl: String },
38 UnsupportedVersionTarget { annotation: String, target: String },
40 VersionedVersionEnum { annotation: String, ident: String },
42 DuplicateLifecycleAnnotation { annotation: String, decl: String },
44 EmptyAvailability {
46 decl: String,
47 added: String,
48 removed: String,
49 },
50 ChildOutsideParent {
52 decl: String,
53 parent: String,
54 version: String,
55 },
56 DanglingReference {
58 decl: String,
59 reference: String,
60 version: String,
61 },
62 UnversionedSpecification { selection: String },
64 UnknownSelectedVersion { selection: String, declared: String },
66 AmbiguousSelectedVersion {
68 selection: String,
69 first: String,
70 second: String,
71 },
72 UnknownVersion { index: usize },
74 ConflictingSelection { first: String, second: String },
76 EmptySelection,
78 SelectionRequiresOneVersion { selection: String },
80 UnknownVersionLayout { value: String },
82 DuplicateWireName {
85 container: String,
86 wire: String,
87 first: String,
88 second: String,
89 version: Option<String>,
90 },
91}
92
93impl fmt::Display for VersioningError {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 match self {
96 Self::VersionOutsideEnum { target } => write!(
97 f,
98 "xidl versioning: @version is only valid on an enum declaration, not on {target}"
99 ),
100 Self::DuplicateVersionEnum { first, second } => write!(
101 f,
102 "xidl versioning: multiple @version enums declared: {first} and {second}"
103 ),
104 Self::EmptyVersionEnum { ident } => write!(
105 f,
106 "xidl versioning: the @version enum {ident} declares no versions"
107 ),
108 Self::DuplicateVersionValue {
109 value,
110 first,
111 second,
112 } => write!(
113 f,
114 "xidl versioning: versions {first} and {second} both resolve to value \"{value}\""
115 ),
116 Self::MissingVersionEnum { annotation, decl } => write!(
117 f,
118 "xidl versioning: {annotation} on {decl} requires a @version enum in the specification"
119 ),
120 Self::MalformedVersionReference { annotation, decl } => write!(
121 f,
122 "xidl versioning: {annotation} on {decl} requires a version reference like Versions::v1"
123 ),
124 Self::MalformedVersionMarker { decl } => {
125 write!(
126 f,
127 "xidl versioning: @version on {decl} must be bare or declare in=... and name=..."
128 )
129 }
130 Self::MalformedVersionParameter { decl, reason } => {
131 write!(f, "xidl versioning: @version on {decl}: {reason}")
132 }
133 Self::DuplicateVersionParameter { decl } => write!(
134 f,
135 "xidl versioning: @version on {decl} is declared more than once"
136 ),
137 Self::UnknownVersionReference {
138 annotation,
139 decl,
140 reference,
141 declared,
142 } => write!(
143 f,
144 "xidl versioning: {annotation} on {decl} references {reference}, which is not declared ({declared})"
145 ),
146 Self::UnsupportedVersionAnnotation { name, decl } => {
147 write!(f, "xidl versioning: {name} on {decl} is not supported; ")?;
148 if name.eq_ignore_ascii_case("@renamedFrom") {
149 write!(
150 f,
151 "use @rename(\"wire_name\") for the serialized name; use @added/@removed declarations for changes between versions"
152 )
153 } else {
154 write!(
155 f,
156 "use @version, @added and @removed for version availability"
157 )
158 }
159 }
160 Self::UnsupportedVersionTarget { annotation, target } => write!(
161 f,
162 "xidl versioning: {annotation} cannot be applied to {target}"
163 ),
164 Self::VersionedVersionEnum { annotation, ident } => write!(
165 f,
166 "xidl versioning: the @version enum {ident} cannot carry {annotation}"
167 ),
168 Self::DuplicateLifecycleAnnotation { annotation, decl } => {
169 write!(f, "xidl versioning: duplicate {annotation} on {decl}")
170 }
171 Self::EmptyAvailability {
172 decl,
173 added,
174 removed,
175 } => write!(
176 f,
177 "xidl versioning: {decl} is unavailable in every version (@added({added}) and @removed({removed}) leave an empty interval)"
178 ),
179 Self::ChildOutsideParent {
180 decl,
181 parent,
182 version,
183 } => write!(
184 f,
185 "xidl versioning: {decl} is annotated at {version}, outside the availability of {parent}"
186 ),
187 Self::DanglingReference {
188 decl,
189 reference,
190 version,
191 } => write!(
192 f,
193 "xidl versioning: {decl} references {reference}, which does not exist in {version}"
194 ),
195 Self::UnversionedSpecification { selection } => write!(
196 f,
197 "xidl versioning: version selection {selection} requires a @version enum in the specification"
198 ),
199 Self::UnknownSelectedVersion {
200 selection,
201 declared,
202 } => write!(
203 f,
204 "xidl versioning: version {selection} is not declared ({declared})"
205 ),
206 Self::AmbiguousSelectedVersion {
207 selection,
208 first,
209 second,
210 } => write!(
211 f,
212 "xidl versioning: version {selection} matches both {first} and {second}; use the member ident"
213 ),
214 Self::UnknownVersion { index } => write!(
215 f,
216 "xidl versioning: version position {index} is not part of the declared timeline"
217 ),
218 Self::ConflictingSelection { first, second } => write!(
219 f,
220 "xidl versioning: {first} and {second} cannot both be set"
221 ),
222 Self::EmptySelection => write!(
223 f,
224 "xidl versioning: the version selection is empty; name at least one version or use \"*\""
225 ),
226 Self::SelectionRequiresOneVersion { selection } => write!(
227 f,
228 "xidl versioning: {selection} selects one version; use the plural version property with \"*\" for every version"
229 ),
230 Self::UnknownVersionLayout { value } => write!(
231 f,
232 "xidl versioning: unknown version layout \"{value}\"; expected \"merged\" or \"per_version\""
233 ),
234 Self::DuplicateWireName {
235 container,
236 wire,
237 first,
238 second,
239 version,
240 } => match version {
241 Some(version) => write!(
242 f,
243 "xidl versioning: {first} and {second} both serialize as \"{wire}\" in version {version}; effective wire names must stay unique inside {container} for every version"
244 ),
245 None => write!(
246 f,
247 "xidl versioning: {first} and {second} both serialize as \"{wire}\"; effective wire names must stay unique inside {container}"
248 ),
249 },
250 }
251 }
252}
253
254impl Error for VersioningError {}