apollo_client/conf/
meta.rs1use crate::{
4 conf::requests::{FetchRequest, WatchRequest},
5 utils::canonicalize_namespace,
6};
7use serde::{Deserialize, Serialize};
8use std::{
9 borrow::Cow,
10 fmt::{self, Display},
11};
12
13pub(crate) const UNINITIALIZED_NOTIFICATION_ID: i32 = -1;
14
15#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub struct Notification {
19 pub namespace_name: String,
20 pub notification_id: i32,
21}
22
23impl Default for Notification {
24 fn default() -> Self {
25 Self {
26 namespace_name: "".to_string(),
27 notification_id: UNINITIALIZED_NOTIFICATION_ID,
28 }
29 }
30}
31
32impl Notification {
33 #[inline]
34 pub(crate) fn is_uninitialized(&self) -> bool {
35 self.notification_id == UNINITIALIZED_NOTIFICATION_ID
36 }
37
38 pub(crate) fn update_notifications(older: &mut [Self], newer: &[Self]) {
50 for newer_item in newer {
51 let newer_namespace_name = canonicalize_namespace(&newer_item.namespace_name);
52 for older_item in older.iter_mut() {
53 if canonicalize_namespace(&older_item.namespace_name) == newer_namespace_name {
54 older_item.notification_id = newer_item.notification_id;
55 }
56 }
57 }
58 }
59
60 pub(crate) fn create_fetch_requests(
61 notifications: impl IntoIterator<Item = Self>,
62 watch: &WatchRequest,
63 ) -> Vec<FetchRequest> {
64 notifications
65 .into_iter()
66 .map(|notification| FetchRequest::from_watch(watch, notification.namespace_name))
67 .collect()
68 }
69}
70
71implement_json_perform_response_for! { Vec<Notification> }
72
73#[derive(Debug, Clone, PartialEq)]
75pub enum IpValue {
76 #[cfg(feature = "host-name")]
78 #[cfg_attr(docsrs, doc(cfg(feature = "host-name")))]
79 HostName,
80
81 #[cfg(feature = "host-ip")]
83 #[cfg_attr(docsrs, doc(cfg(feature = "host-ip")))]
84 HostIp,
85
86 #[cfg(feature = "host-ip")]
88 #[cfg_attr(docsrs, doc(cfg(feature = "host-ip")))]
89 HostCidr(cidr_utils::cidr::IpCidr),
90
91 Custom(String),
93}
94
95impl IpValue {
96 #[cfg(feature = "host-name")]
97 fn get_host_name() -> &'static str {
98 cfg_if::cfg_if! {
99 if #[cfg(test)] {
100 "test-host-name"
101 } else {
102 crate::utils::get_host_name()
103 }
104 }
105 }
106
107 #[cfg(feature = "host-ip")]
108 fn get_all_addrs() -> &'static [std::net::IpAddr] {
109 cfg_if::cfg_if! {
110 if #[cfg(test)] {
111 static TEST_IPS: [std::net::IpAddr; 2] = [
112 std::net::IpAddr::V4(std::net::Ipv4Addr::new(10, 2, 0, 1)),
113 std::net::IpAddr::V4(std::net::Ipv4Addr::new(10, 3, 0, 1)),
114 ];
115 &TEST_IPS
116 } else {
117 crate::utils::get_all_addrs()
118 }
119 }
120 }
121}
122
123impl Display for IpValue {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 write!(
126 f,
127 "{}",
128 match self {
129 #[cfg(feature = "host-name")]
130 IpValue::HostName => Cow::Borrowed(Self::get_host_name()),
131
132 #[cfg(feature = "host-ip")]
133 IpValue::HostIp => {
134 Self::get_all_addrs()
135 .first()
136 .map(|s| Cow::Owned(s.to_string()))
137 .unwrap_or(Cow::Borrowed("127.0.0.1"))
138 }
139
140 #[cfg(feature = "host-ip")]
141 IpValue::HostCidr(cidr) => {
142 Self::get_all_addrs()
143 .iter()
144 .find(|addr| cidr.contains(*addr))
145 .map(|s| Cow::Owned(s.to_string()))
146 .unwrap_or(Cow::Borrowed("127.0.0.1"))
147 }
148
149 IpValue::Custom(s) => Cow::Borrowed(s.as_ref()),
150 }
151 )
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158 use std::str::FromStr;
159
160 #[test]
161 fn test_notification_new() {
162 let notification = Notification {
163 namespace_name: "foo.properties".to_string(),
164 ..Default::default()
165 };
166 assert_eq!(notification.namespace_name, "foo.properties");
167 assert_eq!(notification.notification_id, -1);
168
169 let notification = Notification {
170 namespace_name: "foo.yaml".to_string(),
171 notification_id: 10,
172 };
173 assert_eq!(notification.namespace_name, "foo.yaml");
174 assert_eq!(notification.notification_id, 10);
175 }
176
177 #[test]
178 fn test_update_notifications() {
179 let mut notifications = [
180 Notification {
181 namespace_name: "foo".to_string(),
182 ..Default::default()
183 },
184 Notification {
185 namespace_name: "bar".to_string(),
186 notification_id: 10,
187 },
188 ];
189 Notification::update_notifications(
190 &mut notifications,
191 &[Notification {
192 namespace_name: "foo".to_string(),
193 notification_id: 100,
194 }],
195 );
196 assert_eq!(
197 notifications,
198 [
199 Notification {
200 namespace_name: "foo".to_string(),
201 notification_id: 100,
202 },
203 Notification {
204 namespace_name: "bar".to_string(),
205 notification_id: 10,
206 },
207 ]
208 );
209 }
210
211 #[test]
212 fn test_ip_value_display() {
213 #[cfg(feature = "host-name")]
214 assert_eq!(IpValue::HostName.to_string(), "test-host-name");
215
216 #[cfg(feature = "host-ip")]
217 assert_eq!(IpValue::HostIp.to_string(), "10.2.0.1");
218
219 #[cfg(feature = "host-ip")]
220 assert_eq!(
221 IpValue::HostCidr(cidr_utils::cidr::IpCidr::from_str("10.3.0.0/16").unwrap())
222 .to_string(),
223 "10.3.0.1"
224 );
225
226 assert_eq!(
227 IpValue::Custom("custom-ip".to_owned()).to_string(),
228 "custom-ip"
229 );
230 }
231}