1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

//! Error types that can be returned by the Simics crate

use std::path::PathBuf;

/// Result type for fallible functions in the SIMICS API
pub type Result<T> = std::result::Result<T, Error>;

#[allow(unused)]
#[derive(thiserror::Error, Debug)]
/// SIMICS errors, including internal and APIs used
pub enum Error {
    #[error("AttrValue is {actual:?}, expected {expected:?} ({reason})")]
    /// Attribute value type mismatch
    AttrValueType {
        /// The value that could not be converted
        // value: crate::AttrValue,
        /// The actual kind of the Attrvalue
        actual: crate::AttrKind,
        /// The expected kind of the AttrValue
        expected: crate::AttrKind,
        /// The reason the conversion failed
        reason: String,
    },
    #[error("Index {index} out of bounds of list length {length}")]
    /// An attribute value list was indexed out of bounds
    AttrValueListIndexOutOfBounds {
        /// The requested index
        index: usize,
        /// The length of the list
        length: usize,
    },
    #[error("List of length {length} is too large")]
    /// A list was too large, this is rare as the list size limit is extremely large.
    AttrValueListTooLarge {
        /// The actual length of the list
        length: usize,
    },
    #[error("Index {index} out of bounds of dictionary size {size}")]
    /// An attribute value dictionary was indexed out of bounds
    AttrValueDictIndexOutOfBounds {
        /// The requested index
        index: usize,
        /// The size of the dictionary
        size: usize,
    },
    #[error("Dictionary of size {size} is too large")]
    /// An attribute value dictionary was too large. This is rare as teh size limit is extremely
    /// large.
    AttrValueDictTooLarge {
        /// The size of the dictionary
        size: usize,
    },
    #[error("Null data requires zero size")]
    /// Null attribute value data construction attempted without a zero size
    InvalidNullDataSize,
    #[error("Error converting to from {ty} to AttrValue")]
    /// Could not convert a type to an AttrValue
    ToAttrValueConversionError {
        /// The name of the type that could not be converted
        ty: String,
    },
    #[error("Error converting from to {ty}")]
    /// Could not convert from an attribute value to a type
    FromAttrValueConversionError {
        /// The attribute value that could not be converted from
        // value: crate::AttrValue,
        /// The type the value could not be converted into
        ty: String,
    },
    #[error("Error converting to from {ty} to AttrValueType")]
    /// Could not convert to an attribute value type from a type
    ToAttrValueTypeConversionError {
        /// The type that could not be converted to an attribute value type
        ty: String,
    },
    #[error("Error converting to from AttrValueType to {ty} ({reason})")]
    /// Could not convert from an attribute value type to a type
    FromAttrValueTypeConversionError {
        /// The value that could not be converted from an attribute value type
        // value: crate::AttrValueType,
        /// The type that could not be converted from an attribute value type
        ty: String,
        /// The reason the conversion failed
        reason: String,
    },
    #[error("Error converting to from {ty} to AttrValue: {source}")]
    /// Could not convert to an attribute value from a type, because of a nested error
    NestedToAttrValueConversionError {
        /// The type that could not be converted to an attribute value
        ty: String,
        /// The nested error that caused this conversion to fail
        source: Box<Error>,
    },
    #[error("Error converting AttrValue to {ty}: {source}")]
    /// Could not convert from an attribute value to a type, because of a nested error
    NestedFromAttrValueConversionError {
        /// The value that could not be converted
        // value: crate::AttrValue,
        /// The type that the value could not be converted into
        ty: String,
        /// The nested error that caused this conversion to fail
        source: Box<Error>,
    },
    #[error("Error converting to from {ty} to AttrValueType: {source}")]
    /// Could not convert to an attribute value type from a type, because of a nested error
    NestedToAttrValueTypeConversionError {
        /// The type that could not be converted to an attribute value type
        ty: String,
        /// The nested error that caused this conversion to fail
        source: Box<Error>,
    },
    #[error("Error converting to from AttrValueType to {ty}: {source}")]
    /// could not convert from an attribute value type to a type, because of a nested error
    NestedFromAttrValueTypeConversionError {
        /// The type that could not be converted from an attribute value type
        ty: String,
        /// The nested error that caused this conversion to fail
        source: Box<Error>,
    },
    #[error("Key {key} not found")]
    /// A key was not found in an attribute value dictionary
    AttrValueDictMissingKey {
        /// The key that was not found
        key: String,
    },
    #[error("AttrValue list is non-homogeneous")]
    /// An attribute value list was non-homogeneous during an operation that required a
    /// homogeneous list
    NonHomogeneousList,
    #[error("AttrValue dictionary is non-homogeneous")]
    /// An attribute value dictionary was non-homogeneous during an operation that required a
    /// homogeneous dictionary
    NonHomogeneousDict,
    #[error("Could not convert to string")]
    /// Error converting a value to a string
    ToString,
    #[error("File {file} was not found in lookup")]
    /// A file was not found
    FileLookup {
        /// The file that was not found
        file: String,
    },
    #[error("Failed to create class {name}: {message}")]
    /// A class creation operation failed
    CreateClass {
        /// The name of the class to be created
        name: String,
        /// The error message
        message: String,
    },
    #[error("Failed to register {name}: {message}")]
    /// Registration of an interface failed
    RegisterInterface {
        /// The name of the interface that failed to register
        name: String,
        /// The error message
        message: String,
    },
    #[error("Could not find class with name {name}")]
    /// A class could not be found
    ClassNotFound {
        /// The name of the class that could not be found
        name: String,
    },
    #[error("Could not find object with name {name}")]
    /// An object could not be found
    ObjectNotFound {
        /// The name of the object that could not be found
        name: String,
    },
    #[error("Could not create object: {message}")]
    /// Object creation failed
    CreateObject {
        /// The reason object creation failed
        message: String,
    },
    #[error("No current checkpoint directory: {message}")]
    /// A checkpoint directory was missing when it was required
    CurrentCheckpointDir {
        /// The source error message
        message: String,
    },
    #[error("No matching event found")]
    /// An event matching a query was not found
    NoEventFound,
    #[error("No method {method} found on interface")]
    /// An interface did not have a given method
    NoInterfaceMethod {
        /// The name of the missing method
        method: String,
    },
    #[error("{exception:?}: {msg}")]
    /// An internal error that comes from the sys API. These exceptions are wrapped in a message
    /// and reported as Rust errors
    SimicsException {
        /// The inner exception
        exception: crate::SimException,
        /// The string describing the exception
        msg: String,
    },
    #[error("This registration type is not supported for this hap")]
    /// An error attempting to register a hap with an unsupported type
    HapRegistrationType,
    #[error("This deletion type is not supported for this hap")]
    /// An error attempting to delete a hap with an unsupported type
    HapDeleteType,
    #[error("Value size {actual} is too large (expected <= {expected})")]
    /// A value was too large
    ValueTooLarge {
        /// The expected size
        expected: usize,
        /// The actual size
        actual: usize,
    },
    #[error("{path:?} is not a directory")]
    /// A path that should have been a directory was not
    NotADirectory {
        /// The path
        path: PathBuf,
    },
    #[error("Unrecognized extension for library type for file {library_type}")]
    /// An extension of a library file was not recognized
    UnrecognizedLibraryTypeExtension {
        /// The file
        library_type: String,
    },
    #[error("File matching pattern {pattern} not found in directory {directory:?}")]
    /// A file could not be found matching a given pattern
    FileNotFoundInDirectory {
        /// The directory that was searched
        directory: PathBuf,
        /// The pattern that was searched for
        pattern: String,
    },

    // Transparently wrapped errors from std
    #[error(transparent)]
    /// A wrapped std::num::TryFromIntError
    TryFromIntError(#[from] std::num::TryFromIntError),
    #[error(transparent)]
    /// A wrapped std::str::Utf8Error
    Utf8Error(#[from] std::str::Utf8Error),
    #[error(transparent)]
    /// A wrapped std::ffi::NulError
    NulError(#[from] std::ffi::NulError),
    #[error(transparent)]
    /// A wrapped std::io::Error
    IoError(#[from] std::io::Error),
    #[error(transparent)]
    /// A wrapped std::path::StripPrefixError
    RegexError(#[from] regex::Error),
    // Anyhow error type to allow wrapping any other errors (e.g. from other crates in the
    // workspace)
    #[error(transparent)]
    /// A wrapped anyhow::Error
    Other(#[from] anyhow::Error),
    #[error(transparent)]
    /// A wrapped std::convert::Infallible
    Infallible(#[from] std::convert::Infallible),
}