Skip to main content

smart_id_rust_client/models/api/
response.rs

1use crate::error::{Result, SmartIdClientError};
2use serde::{Deserialize, Serialize};
3
4/// Represents the response from the Smart-ID API.
5///
6/// This enum can either be a success response containing the data of type `T`,
7/// or an error response containing a `SmartIDErrorResponse`.
8///
9/// It allows you to easily handle receiving two completely different response structures from the API.
10///
11/// # Example
12/// // We define a type for the response, which is a `SessionStatus`.
13/// pub(crate) type SessionResponse = SmartIdAPIResponse<SessionStatus>;
14/// // Get will now return a `SessionResponse` that contains either a `SessionStatus` or a `SmartIDErrorResponse`.
15/// let session_response = get::<SessionResponse>("path".to_string(), None).await?;
16/// // If the response was an error, this line will pass the error to the caller. Otherwise, it will assign the data to `session_status`.
17///  let session_status = session_response.into_result()?;
18#[derive(Debug, Deserialize)]
19#[serde(untagged)]
20pub(crate) enum SmartIdAPIResponse<T> {
21    Success(T),
22    Error(SmartIDErrorResponse),
23}
24
25impl<T> SmartIdAPIResponse<T> {
26    /// Converts the `SmartIdAPIResponse` into a `Result<T>`.
27    /// Read the documentation for `SmartIdAPIResponse` for more information.
28    ///
29    /// If the response is a success, it returns `Ok(T)`.
30    /// If the response is an error, it maps the error response to the appropriate error and returns it.
31    pub fn into_result(self) -> Result<T> {
32        match self {
33            SmartIdAPIResponse::Success(data) => Ok(data),
34            SmartIdAPIResponse::Error(error) => match error.status {
35                400 => Err(SmartIdClientError::BadRequestException),
36                401 => Err(
37                    SmartIdClientError::RelyingPartyAccountConfigurationException(
38                        "Request is unauthorized",
39                    ),
40                ),
41                403 => Err(
42                    SmartIdClientError::RelyingPartyAccountConfigurationException(
43                        "Request is forbidden",
44                    ),
45                ),
46                404 => Err(SmartIdClientError::NotFoundException),
47                471 => Err(SmartIdClientError::NoSuitableAccountOfRequestedTypeFoundException),
48                472 => Err(SmartIdClientError::PersonShouldViewSmartIdPortalException),
49                480 => Err(SmartIdClientError::ClientOutdatedException),
50                580 => Err(SmartIdClientError::SystemIsUnderMaintenanceException),
51                _ => Err(SmartIdClientError::SmartIDAPIException(format!(
52                    "Unknown error: {}",
53                    error.status
54                ))),
55            },
56        }
57    }
58}
59
60#[derive(Serialize, Deserialize, Debug)]
61#[serde(rename_all = "camelCase")]
62pub(crate) struct SmartIDErrorResponse {
63    #[serde(rename = "type")]
64    pub error_type: String,
65    pub title: String,
66    pub status: i64,
67    pub detail: String,
68    // pub instance: Option<_>,
69    // pub properties: Option<_>,
70    pub code: i64,
71    pub message: String,
72}