Implement ApiType and UpdaterType in order to be able to directly use
the CIDR and MacAddress types in the API. Their schema is a string and
they get (de-)serialized by the respective FromStr / Display
implementations.

Signed-off-by: Stefan Hanreich <s.hanre...@proxmox.com>
---
 proxmox-network-types/Cargo.toml         |  1 +
 proxmox-network-types/src/ip_address.rs  | 36 ++++++++++++++++++++++++
 proxmox-network-types/src/mac_address.rs | 25 ++++++++++++++++
 3 files changed, 62 insertions(+)

diff --git a/proxmox-network-types/Cargo.toml b/proxmox-network-types/Cargo.toml
index aa6d66bc..3dda51d4 100644
--- a/proxmox-network-types/Cargo.toml
+++ b/proxmox-network-types/Cargo.toml
@@ -19,3 +19,4 @@ proxmox-schema = { workspace = true, features = [ 
"api-macro", "api-types" ], op
 
 [features]
 default = []
+api-types = ["dep:proxmox-schema", "dep:regex"]
diff --git a/proxmox-network-types/src/ip_address.rs 
b/proxmox-network-types/src/ip_address.rs
index 355547b1..827141b9 100644
--- a/proxmox-network-types/src/ip_address.rs
+++ b/proxmox-network-types/src/ip_address.rs
@@ -5,6 +5,12 @@ use std::net::{AddrParseError, IpAddr, Ipv4Addr, Ipv6Addr};
 use serde_with::{DeserializeFromStr, SerializeDisplay};
 use thiserror::Error;
 
+#[cfg(feature = "api-types")]
+use proxmox_schema::{ApiType, Schema, UpdaterType};
+
+#[cfg(feature = "api-types")]
+use proxmox_schema::api_types::{CIDR_SCHEMA, CIDR_V4_SCHEMA, CIDR_V6_SCHEMA};
+
 /// The family (v4 or v6)  of an IP address or CIDR prefix
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum Family {
@@ -48,6 +54,16 @@ pub enum Cidr {
     Ipv6(Ipv6Cidr),
 }
 
+#[cfg(feature = "api-types")]
+impl ApiType for Cidr {
+    const API_SCHEMA: Schema = CIDR_SCHEMA;
+}
+
+#[cfg(feature = "api-types")]
+impl UpdaterType for Cidr {
+    type Updater = Option<Cidr>;
+}
+
 impl Cidr {
     pub fn new_v4(addr: impl Into<Ipv4Addr>, mask: u8) -> Result<Self, 
CidrError> {
         Ok(Cidr::Ipv4(Ipv4Cidr::new(addr, mask)?))
@@ -139,6 +155,16 @@ pub struct Ipv4Cidr {
     mask: u8,
 }
 
+#[cfg(feature = "api-types")]
+impl ApiType for Ipv4Cidr {
+    const API_SCHEMA: Schema = CIDR_V4_SCHEMA;
+}
+
+#[cfg(feature = "api-types")]
+impl UpdaterType for Ipv4Cidr {
+    type Updater = Option<Ipv4Cidr>;
+}
+
 impl Ipv4Cidr {
     pub fn new(addr: impl Into<Ipv4Addr>, mask: u8) -> Result<Self, CidrError> 
{
         if mask > IPV4_LENGTH {
@@ -217,6 +243,16 @@ pub struct Ipv6Cidr {
     mask: u8,
 }
 
+#[cfg(feature = "api-types")]
+impl ApiType for Ipv6Cidr {
+    const API_SCHEMA: Schema = CIDR_V6_SCHEMA;
+}
+
+#[cfg(feature = "api-types")]
+impl UpdaterType for Ipv6Cidr {
+    type Updater = Option<Ipv6Cidr>;
+}
+
 impl Ipv6Cidr {
     pub fn new(addr: impl Into<Ipv6Addr>, mask: u8) -> Result<Self, CidrError> 
{
         if mask > IPV6_LENGTH {
diff --git a/proxmox-network-types/src/mac_address.rs 
b/proxmox-network-types/src/mac_address.rs
index d347076e..4ad82699 100644
--- a/proxmox-network-types/src/mac_address.rs
+++ b/proxmox-network-types/src/mac_address.rs
@@ -4,6 +4,9 @@ use std::net::Ipv6Addr;
 use serde_with::{DeserializeFromStr, SerializeDisplay};
 use thiserror::Error;
 
+#[cfg(feature = "api-types")]
+use proxmox_schema::{const_regex, ApiStringFormat, ApiType, Schema, 
StringSchema, UpdaterType};
+
 #[derive(Error, Debug)]
 pub enum MacAddressError {
     #[error("the hostname must be from 1 to 63 characters long")]
@@ -12,12 +15,34 @@ pub enum MacAddressError {
     InvalidSymbols,
 }
 
+#[cfg(feature = "api-types")]
+const_regex! {
+    pub MAC_ADDRESS_REGEX = r"([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}";
+}
+
+#[cfg(feature = "api-types")]
+pub const MAC_ADDRESS_FORMAT: ApiStringFormat = 
ApiStringFormat::Pattern(&MAC_ADDRESS_REGEX);
+
 /// EUI-48 MAC Address
 #[derive(
     Clone, Copy, Debug, DeserializeFromStr, SerializeDisplay, PartialEq, Eq, 
Hash, PartialOrd, Ord,
 )]
 pub struct MacAddress([u8; 6]);
 
+#[cfg(feature = "api-types")]
+impl ApiType for MacAddress {
+    const API_SCHEMA: Schema = StringSchema::new("MAC address")
+        .min_length(17)
+        .max_length(17)
+        .format(&MAC_ADDRESS_FORMAT)
+        .schema();
+}
+
+#[cfg(feature = "api-types")]
+impl UpdaterType for MacAddress {
+    type Updater = Option<MacAddress>;
+}
+
 static LOCAL_PART: [u8; 8] = [0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
 static EUI64_MIDDLE_PART: [u8; 2] = [0xFF, 0xFE];
 
-- 
2.39.5


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to