assemblyline_client/
types.rs

1use std::fmt::Display;
2
3
4/// A value that contains one of the ways to authenticate to Assemblyline
5pub enum Authentication {
6    /// Authenticate with a password
7    Password{
8        /// The name of the user account connecting
9        username: String,
10        /// The password of the user connecting
11        password: String
12    },
13    /// Authenticate with an api key
14    ApiKey{
15        /// The name of the user account connecting
16        username: String,
17        /// The API key of the user connecting
18        key: String
19    },
20    /// Authenticate with an oauth token
21    OAuth{
22        /// Oauth provider
23        provider: String,
24        /// Oauth token
25        token: String
26    }
27}
28
29
30/// Short name for serde json's basic map type
31pub type JsonMap = serde_json::Map<String, serde_json::Value>;
32
33/// Set of possible errors returned by client
34#[derive(Debug)]
35pub enum Error {
36    /// An error produced by the client's communication with the server
37    Client{
38        /// A message describing the error
39        message: String,
40        /// HTTP status code associated
41        status: u32,
42        /// Server's API version if available
43        api_version: Option<String>,
44        /// Server's response details if available
45        api_response: Option<String>
46    },
47    /// An error that occured during a failed communication with the server
48    TransportError(String),
49    /// An invalid HTTP header name or value was provided
50    InvalidHeader,
51    /// The server's response was truncated, corrupted, or malformed
52    MalformedResponse,
53    /// A string could not be converted into a sha256
54    InvalidSha256,
55    /// A path was provided for submission that couldn't be used
56    InvalidSubmitFilePath,
57    /// A url was provided for submission and a file name couldn't be parsed
58    InvalidSubmitUrl,
59    /// An error that has bubbled up from an IO call
60    IO(std::io::Error),
61    /// An error caused by failing to serialize or deserialize a message
62    Serialization(serde_json::Error),
63    /// An unexpected state was reached serializing submission parameters
64    ParameterSerialization,
65    /// A configuration value which has caused errors
66    Configuration(String),
67}
68
69impl Error {
70    pub (crate) fn client_error(message: String, status: u32) -> Self {
71        return Error::Client { message, status, api_response: None, api_version: None }
72    }
73}
74
75impl Display for Error {
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77        match self {
78            Error::Client { message, status, .. } =>
79                f.write_fmt(format_args!("Client error [{status}]: {message}")),
80            Error::TransportError(message) =>
81                f.write_fmt(format_args!("Error communicating with server: {message}")),
82            Error::InvalidHeader =>
83                f.write_str("An invalid HTTP header name or value was encountered"),
84            Error::MalformedResponse =>
85                f.write_str("A server response was malformed"),
86            Error::InvalidSha256 =>
87                f.write_str("An invalid SHA256 string was provided"),
88            Error::InvalidSubmitFilePath =>
89                f.write_str("An invalid path was given for submission"),
90            Error::InvalidSubmitUrl =>
91                f.write_str("An invalid URL was given for submission, try setting the file name explicitly"),
92            Error::IO(error) =>
93                f.write_fmt(format_args!("An IO error ocurred: {error}")),
94            Error::Serialization(error) =>
95                f.write_fmt(format_args!("An error occurred serializing a body: {error}")),
96            Error::ParameterSerialization =>
97                f.write_str("Parameter serialization yielded unexpected type."),
98            Error::Configuration(message) =>
99                f.write_fmt(format_args!("A configuration parameter caused an error: {message}")),
100        }
101    }
102}
103
104impl From<reqwest::Error> for Error {
105    fn from(value: reqwest::Error) -> Self {
106        if let Some(code) = value.status() {
107            Error::client_error(value.to_string(), code.as_u16() as u32)
108        } else {
109            Error::TransportError(value.to_string())
110        }
111    }
112}
113
114impl From<reqwest::header::InvalidHeaderName> for Error {
115    fn from(_value: reqwest::header::InvalidHeaderName) -> Self {
116        Self::InvalidHeader
117    }
118}
119
120impl From<reqwest::header::InvalidHeaderValue> for Error {
121    fn from(_value: reqwest::header::InvalidHeaderValue) -> Self {
122        Self::InvalidHeader
123    }
124}
125
126impl From<serde_json::Error> for Error {
127    fn from(value: serde_json::Error) -> Self {
128        Self::Serialization(value)
129    }
130}
131
132impl From<std::io::Error> for Error {
133    fn from(value: std::io::Error) -> Self {
134        Self::IO(value)
135    }
136}
137
138impl From<url::ParseError> for Error {
139    fn from(_value: url::ParseError) -> Self {
140        Self::InvalidSubmitUrl
141    }
142}
143
144impl From<rustls::Error> for Error {
145    fn from(value: rustls::Error) -> Self {
146        Self::Configuration(format!("Error loading tls certificates: {value}"))
147    }
148}
149
150impl std::error::Error for Error {
151
152}
153
154pub type Result<T> = std::result::Result<T, Error>;
155
156/// A convenience trait that lets you pass true, false, or None for boolean arguments
157pub trait IBool: Into<Option<bool>> + Copy {}
158impl<T: Into<Option<bool>> + Copy> IBool for T {}