use serde::{Deserialize, Serialize};
use crate::contract::{CoreRequest, CoreResponse};
use crate::core_service::{CoreService, ServiceError};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ErrorCode {
InvalidJson,
InvalidRequest,
ItemNotFound,
Launch,
Store,
Config,
Provider,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ErrorResponse {
pub code: ErrorCode,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(tag = "status", rename_all = "snake_case")]
pub enum TransportResponse {
Ok { response: CoreResponse },
Err { error: ErrorResponse },
}
pub fn handle_request(service: &CoreService, request: CoreRequest) -> TransportResponse {
match service.handle_command(request) {
Ok(response) => TransportResponse::Ok { response },
Err(error) => TransportResponse::Err {
error: map_service_error(error),
},
}
}
pub fn handle_json(service: &CoreService, payload: &str) -> String {
let response = match serde_json::from_str::<CoreRequest>(payload) {
Ok(request) => handle_request(service, request),
Err(error) => TransportResponse::Err {
error: ErrorResponse {
code: ErrorCode::InvalidJson,
message: error.to_string(),
},
},
};
serde_json::to_string(&response).expect("transport response should serialize")
}
fn map_service_error(error: ServiceError) -> ErrorResponse {
match error {
ServiceError::InvalidRequest(message) => ErrorResponse {
code: ErrorCode::InvalidRequest,
message,
},
ServiceError::ItemNotFound(message) => ErrorResponse {
code: ErrorCode::ItemNotFound,
message,
},
ServiceError::Launch(message) => ErrorResponse {
code: ErrorCode::Launch,
message: message.to_string(),
},
ServiceError::Store(message) => ErrorResponse {
code: ErrorCode::Store,
message: message.to_string(),
},
ServiceError::Config(message) => ErrorResponse {
code: ErrorCode::Config,
message,
},
ServiceError::Provider(message) => ErrorResponse {
code: ErrorCode::Provider,
message: message.to_string(),
},
}
}