runbeam_sdk/runbeam_api/
types.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4/// Runbeam API error type
5///
6/// Represents all possible errors that can occur when interacting with
7/// the Runbeam Cloud API or performing related operations.
8#[derive(Debug)]
9pub enum RunbeamError {
10    /// JWT validation failed
11    JwtValidation(String),
12    /// API request failed (network, HTTP, or response parsing error)
13    Api(ApiError),
14    /// Token storage operation failed
15    Storage(crate::storage::StorageError),
16    /// Configuration error
17    Config(String),
18}
19
20impl fmt::Display for RunbeamError {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        match self {
23            RunbeamError::JwtValidation(msg) => write!(f, "JWT validation failed: {}", msg),
24            RunbeamError::Api(err) => write!(f, "API error: {}", err),
25            RunbeamError::Storage(err) => write!(f, "Storage error: {}", err),
26            RunbeamError::Config(msg) => write!(f, "Configuration error: {}", msg),
27        }
28    }
29}
30
31impl std::error::Error for RunbeamError {}
32
33impl From<ApiError> for RunbeamError {
34    fn from(err: ApiError) -> Self {
35        RunbeamError::Api(err)
36    }
37}
38
39impl From<crate::storage::StorageError> for RunbeamError {
40    fn from(err: crate::storage::StorageError) -> Self {
41        RunbeamError::Storage(err)
42    }
43}
44
45impl From<jsonwebtoken::errors::Error> for RunbeamError {
46    fn from(err: jsonwebtoken::errors::Error) -> Self {
47        RunbeamError::JwtValidation(err.to_string())
48    }
49}
50
51/// API-specific errors
52#[derive(Debug)]
53pub enum ApiError {
54    /// Network error (connection, timeout, etc.)
55    Network(String),
56    /// HTTP error with status code
57    Http { status: u16, message: String },
58    /// Failed to parse response
59    Parse(String),
60    /// Request building failed
61    Request(String),
62}
63
64impl fmt::Display for ApiError {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        match self {
67            ApiError::Network(msg) => write!(f, "Network error: {}", msg),
68            ApiError::Http { status, message } => {
69                write!(f, "HTTP {} error: {}", status, message)
70            }
71            ApiError::Parse(msg) => write!(f, "Parse error: {}", msg),
72            ApiError::Request(msg) => write!(f, "Request error: {}", msg),
73        }
74    }
75}
76
77impl std::error::Error for ApiError {}
78
79impl From<reqwest::Error> for ApiError {
80    fn from(err: reqwest::Error) -> Self {
81        if err.is_timeout() {
82            ApiError::Network("Request timeout".to_string())
83        } else if err.is_connect() {
84            ApiError::Network(format!("Connection failed: {}", err))
85        } else if let Some(status) = err.status() {
86            ApiError::Http {
87                status: status.as_u16(),
88                message: err.to_string(),
89            }
90        } else {
91            ApiError::Network(err.to_string())
92        }
93    }
94}
95
96/// User information from JWT claims
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct UserInfo {
99    pub id: String,
100    pub email: String,
101    pub name: String,
102}
103
104/// Team information from JWT claims
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct TeamInfo {
107    pub id: String,
108    pub name: String,
109}
110
111/// Gateway information returned from authorize endpoint
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct GatewayInfo {
114    pub id: String,
115    pub code: String,
116    pub name: String,
117    #[serde(default)]
118    pub authorized_by: Option<AuthorizedBy>,
119}
120
121/// User who authorized the gateway
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct AuthorizedBy {
124    pub id: String,
125    pub name: String,
126    pub email: String,
127}
128
129/// Response from Runbeam Cloud authorize endpoint
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct AuthorizeResponse {
132    pub machine_token: String,
133    pub expires_in: f64,
134    pub expires_at: String,
135    pub gateway: GatewayInfo,
136    #[serde(default)]
137    pub abilities: Vec<String>,
138}