mod error;
mod response;
pub mod schema;
pub use error::{ApiError, ErrorContext, LegacyErrorCode};
pub use response::{API_VERSION, ApiResponse};
pub use schema::{
ErrorCatalog, ErrorCategoryEntry, ErrorCodeEntry, SchemaExportResult, export_schemas,
generate_api_error_schema, generate_api_response_schema, generate_error_catalog,
};
#[cfg(test)]
mod tests {
use super::*;
use crate::ErrorCode;
#[test]
fn test_success_response_serialization() {
let response = ApiResponse::ok("test command", "test data");
let json = serde_json::to_string(&response).unwrap();
assert!(json.contains("\"success\":true"));
assert!(json.contains("\"api_version\":\"1.0\""));
assert!(json.contains("\"data\":\"test data\""));
}
#[test]
fn test_error_response_serialization() {
let error = ApiError::from_code(ErrorCode::ConfigNotFound);
let response: ApiResponse<()> = ApiResponse::err("config show", error);
let json = serde_json::to_string(&response).unwrap();
assert!(json.contains("\"success\":false"));
assert!(json.contains("\"code\":\"RCH-E001\""));
assert!(json.contains("\"category\":\"config\""));
}
#[test]
fn test_legacy_code_mapping() {
let legacy = LegacyErrorCode::WorkerUnreachable;
let modern = legacy.to_error_code();
assert_eq!(modern, ErrorCode::SshConnectionFailed);
}
#[test]
fn test_error_with_context() {
let error = ApiError::from_code(ErrorCode::WorkerNoneAvailable)
.with_message("All workers are busy")
.with_context("requested_slots", "8")
.with_context("available_workers", "0");
let json = serde_json::to_string(&error).unwrap();
assert!(json.contains("\"requested_slots\":\"8\""));
assert!(json.contains("\"available_workers\":\"0\""));
}
#[test]
fn test_response_with_request_id() {
let response = ApiResponse::ok("status", "healthy").with_request_id("req-12345");
let json = serde_json::to_string(&response).unwrap();
assert!(json.contains("\"request_id\":\"req-12345\""));
}
}