bindcar/
records_types.rs

1// Copyright (c) 2025 Erick Bourgeois, firestoned
2// SPDX-License-Identifier: MIT
3
4//! DNS record data types — the pure request/response structs.
5//!
6//! Free of `axum`, `ApiError` and `AppState` so a library consumer importing
7//! only `bindcar::AddRecordRequest` does not inherit the HTTP server stack.
8//! The handlers that consume these live in [`crate::records`], which re-exports
9//! everything here so existing `bindcar::records::AddRecordRequest` paths keep
10//! working.
11//!
12//! See `.github/community/02-feature-gate-http-server.md` — phase 1 of putting
13//! the server behind a cargo feature.
14
15use serde::{Deserialize, Serialize};
16#[cfg(feature = "server")]
17use utoipa::ToSchema;
18
19/// Request to add a new DNS record
20#[derive(Debug, Serialize, Deserialize)]
21#[cfg_attr(feature = "server", derive(ToSchema))]
22#[serde(rename_all = "camelCase")]
23pub struct AddRecordRequest {
24    /// Record name (e.g., "www", "@" for apex)
25    pub name: String,
26
27    /// Record type (e.g., "A", "AAAA", "CNAME", "MX", "TXT")
28    #[serde(rename = "type")]
29    pub record_type: String,
30
31    /// Record value (e.g., "192.0.2.1" for A record)
32    pub value: String,
33
34    /// TTL in seconds (default: 3600)
35    #[serde(default = "default_ttl")]
36    pub ttl: u32,
37
38    /// Priority (for MX and SRV records)
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub priority: Option<u16>,
41}
42
43/// Request to remove a DNS record
44#[derive(Debug, Serialize, Deserialize)]
45#[cfg_attr(feature = "server", derive(ToSchema))]
46#[serde(rename_all = "camelCase")]
47pub struct RemoveRecordRequest {
48    /// Record name (e.g., "www", "@" for apex)
49    pub name: String,
50
51    /// Record type (e.g., "A", "AAAA", "CNAME")
52    #[serde(rename = "type")]
53    pub record_type: String,
54
55    /// Record value to remove (optional - if omitted, removes all records of this type)
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub value: Option<String>,
58}
59
60/// Request to update a DNS record
61#[derive(Debug, Serialize, Deserialize)]
62#[cfg_attr(feature = "server", derive(ToSchema))]
63#[serde(rename_all = "camelCase")]
64pub struct UpdateRecordRequest {
65    /// Record name (e.g., "www", "@" for apex)
66    pub name: String,
67
68    /// Record type (e.g., "A", "AAAA", "CNAME")
69    #[serde(rename = "type")]
70    pub record_type: String,
71
72    /// Current record value
73    pub current_value: String,
74
75    /// New record value
76    pub new_value: String,
77
78    /// TTL in seconds (default: 3600)
79    #[serde(default = "default_ttl")]
80    pub ttl: u32,
81
82    /// Priority (for MX and SRV records)
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub priority: Option<u16>,
85}
86
87/// Response from record operations
88#[derive(Debug, Serialize, Deserialize)]
89#[cfg_attr(feature = "server", derive(ToSchema))]
90pub struct RecordResponse {
91    pub success: bool,
92    pub message: String,
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub details: Option<serde_json::Value>,
95}
96
97fn default_ttl() -> u32 {
98    3600
99}