vld/primitives/
socket_addr.rs1use serde_json::Value;
2use std::net::SocketAddr;
3
4use crate::error::{FormatKind, IssueCode, SizeOrigin, VldError};
5use crate::schema::VldSchema;
6
7#[derive(Clone)]
10pub struct ZSocketAddr {
11 min_port: Option<u16>,
12 max_port: Option<u16>,
13 custom_type_error: Option<String>,
14}
15
16impl ZSocketAddr {
17 pub fn new() -> Self {
18 Self {
19 min_port: None,
20 max_port: None,
21 custom_type_error: None,
22 }
23 }
24
25 pub fn type_error(mut self, msg: impl Into<String>) -> Self {
26 self.custom_type_error = Some(msg.into());
27 self
28 }
29
30 pub fn min_port(mut self, p: u16) -> Self {
31 self.min_port = Some(p);
32 self
33 }
34
35 pub fn max_port(mut self, p: u16) -> Self {
36 self.max_port = Some(p);
37 self
38 }
39}
40
41impl Default for ZSocketAddr {
42 fn default() -> Self {
43 Self::new()
44 }
45}
46
47impl VldSchema for ZSocketAddr {
48 type Output = SocketAddr;
49
50 fn parse_value(&self, value: &Value) -> Result<Self::Output, VldError> {
51 let s = value.as_str().ok_or_else(|| {
52 crate::primitives::type_error(&self.custom_type_error, "socket_addr", value)
53 })?;
54 let addr = s.parse::<SocketAddr>().map_err(|_| {
55 VldError::from_code_with_value(
56 IssueCode::InvalidFormat {
57 format: FormatKind::SocketAddr,
58 },
59 value,
60 )
61 })?;
62 let port = addr.port();
63 if let Some(min) = self.min_port {
64 if port < min {
65 return Err(VldError::from_code_with_value(
66 IssueCode::TooSmall {
67 origin: SizeOrigin::Port,
68 minimum: min.into(),
69 inclusive: true,
70 },
71 value,
72 ));
73 }
74 }
75 if let Some(max) = self.max_port {
76 if port > max {
77 return Err(VldError::from_code_with_value(
78 IssueCode::TooBig {
79 origin: SizeOrigin::Port,
80 maximum: max.into(),
81 inclusive: true,
82 },
83 value,
84 ));
85 }
86 }
87 Ok(addr)
88 }
89}
90
91#[cfg(feature = "openapi")]
92impl crate::openapi::JsonSchema for ZSocketAddr {
93 fn json_schema(&self) -> serde_json::Value {
94 serde_json::json!({
95 "type": "string",
96 "format": "socket-addr"
97 })
98 }
99}
100
101#[cfg(feature = "openapi")]
102impl crate::openapi::CollectNestedSchemas for ZSocketAddr {}