Skip to main content

feagi_api/common/
response.rs

1// Copyright 2025 Neuraville Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4// API response types
5
6use chrono::Utc;
7use serde::{Deserialize, Serialize};
8#[cfg(feature = "http")]
9use utoipa::ToSchema;
10
11/// Standard API response wrapper
12#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
13#[serde(rename_all = "camelCase")]
14pub struct ApiResponse<T> {
15    /// Whether the operation succeeded
16    pub success: bool,
17
18    /// Response data (present if success = true)
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub data: Option<T>,
21
22    /// ISO 8601 timestamp
23    pub timestamp: String,
24}
25
26impl<T> ApiResponse<T> {
27    /// Create a successful response
28    pub fn success(data: T) -> Self {
29        Self {
30            success: true,
31            data: Some(data),
32            timestamp: Utc::now().to_rfc3339(),
33        }
34    }
35
36    /// Create an error response (no data)
37    pub fn error() -> ApiResponse<()> {
38        ApiResponse {
39            success: false,
40            data: None,
41            timestamp: Utc::now().to_rfc3339(),
42        }
43    }
44}
45
46/// Empty response for operations that return no data
47#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
48pub struct EmptyResponse {
49    /// Operation message
50    pub message: String,
51}
52
53impl EmptyResponse {
54    pub fn new(message: impl Into<String>) -> Self {
55        Self {
56            message: message.into(),
57        }
58    }
59}