lmrc_cloudflare/
types.rs

1//! Common types used across the Cloudflare API.
2
3use serde::{Deserialize, Serialize};
4
5/// Standard Cloudflare API response wrapper.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ApiResponse<T> {
8    /// Whether the request was successful
9    pub success: bool,
10
11    /// The result data
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub result: Option<T>,
14
15    /// Any errors that occurred
16    #[serde(default)]
17    pub errors: Vec<ApiErrorDetail>,
18
19    /// Any messages from the API
20    #[serde(default)]
21    pub messages: Vec<String>,
22
23    /// Result metadata (pagination, etc.)
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub result_info: Option<ResultInfo>,
26}
27
28/// Error detail from Cloudflare API.
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct ApiErrorDetail {
31    /// Error code
32    pub code: i32,
33
34    /// Error message
35    pub message: String,
36}
37
38/// Pagination and result metadata.
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct ResultInfo {
41    /// Current page number
42    pub page: u32,
43
44    /// Number of items per page
45    pub per_page: u32,
46
47    /// Total number of pages
48    pub total_pages: u32,
49
50    /// Total number of items
51    pub count: u32,
52
53    /// Total count across all pages
54    pub total_count: u32,
55}
56
57/// Represents a change to be made (for diff output).
58#[derive(Debug, Clone, PartialEq, Eq)]
59pub enum ChangeAction {
60    /// Create a new resource
61    Create,
62
63    /// Update an existing resource
64    Update,
65
66    /// Delete a resource
67    Delete,
68
69    /// No change needed
70    NoChange,
71}
72
73impl ChangeAction {
74    /// Check if this action will modify resources
75    pub fn is_mutating(&self) -> bool {
76        matches!(
77            self,
78            ChangeAction::Create | ChangeAction::Update | ChangeAction::Delete
79        )
80    }
81}
82
83/// Represents a pending change (for dry-run/diff mode).
84#[derive(Debug, Clone)]
85pub struct Change<T> {
86    /// The action to be performed
87    pub action: ChangeAction,
88
89    /// The current state (if exists)
90    pub current: Option<T>,
91
92    /// The desired state (if applicable)
93    pub desired: Option<T>,
94
95    /// Human-readable description of the change
96    pub description: String,
97}
98
99impl<T> Change<T> {
100    /// Create a new creation change
101    pub fn create(desired: T, description: String) -> Self {
102        Self {
103            action: ChangeAction::Create,
104            current: None,
105            desired: Some(desired),
106            description,
107        }
108    }
109
110    /// Create a new update change
111    pub fn update(current: T, desired: T, description: String) -> Self {
112        Self {
113            action: ChangeAction::Update,
114            current: Some(current),
115            desired: Some(desired),
116            description,
117        }
118    }
119
120    /// Create a no-change entry
121    pub fn no_change(current: T, description: String) -> Self {
122        Self {
123            action: ChangeAction::NoChange,
124            current: Some(current),
125            desired: None,
126            description,
127        }
128    }
129}