1use crate::{
2 bridge::{self, CStringArray},
3 error::Result,
4 ffi,
5 PropertyList, SystemConfigurationError,
6};
7
8#[derive(Clone, Debug)]
9pub struct DynamicStore {
10 raw: bridge::OwnedHandle,
11}
12
13impl DynamicStore {
14 pub fn new(name: &str) -> Result<Self> {
15 Self::create(name, false)
16 }
17
18 pub fn new_with_session_keys(name: &str) -> Result<Self> {
19 Self::create(name, true)
20 }
21
22 fn create(name: &str, use_session_keys: bool) -> Result<Self> {
23 let name = bridge::cstring(name, "sc_dynamic_store_create")?;
24 let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_create(name.as_ptr(), u8::from(use_session_keys)) };
25 let raw = bridge::owned_handle_or_last("sc_dynamic_store_create", raw)?;
26 Ok(Self { raw })
27 }
28
29 pub fn copy_value(&self, key: &str) -> Result<Option<PropertyList>> {
30 let key = bridge::cstring(key, "sc_dynamic_store_copy_value")?;
31 let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_copy_value(self.raw.as_ptr(), key.as_ptr()) };
32 Ok(unsafe { bridge::OwnedHandle::from_raw(raw) }.map(PropertyList::from_owned_handle))
33 }
34
35 pub fn copy_multiple<K, P>(&self, keys: &[K], patterns: &[P]) -> Result<Option<PropertyList>>
36 where
37 K: AsRef<str>,
38 P: AsRef<str>,
39 {
40 let keys = CStringArray::new(keys, "sc_dynamic_store_copy_multiple")?;
41 let patterns = CStringArray::new(patterns, "sc_dynamic_store_copy_multiple")?;
42 let raw = unsafe {
43 ffi::dynamic_store::sc_dynamic_store_copy_multiple(
44 self.raw.as_ptr(),
45 keys.as_ptr(),
46 keys.count(),
47 patterns.as_ptr(),
48 patterns.count(),
49 )
50 };
51 Ok(unsafe { bridge::OwnedHandle::from_raw(raw) }.map(PropertyList::from_owned_handle))
52 }
53
54 pub fn add_value(&self, key: &str, value: &PropertyList) -> Result<()> {
55 let key = bridge::cstring(key, "sc_dynamic_store_add_value")?;
56 let ok = unsafe {
57 ffi::dynamic_store::sc_dynamic_store_add_value(self.raw.as_ptr(), key.as_ptr(), value.as_ptr())
58 };
59 bridge::bool_result("sc_dynamic_store_add_value", ok)
60 }
61
62 pub fn add_temporary_value(&self, key: &str, value: &PropertyList) -> Result<()> {
63 let key = bridge::cstring(key, "sc_dynamic_store_add_temporary_value")?;
64 let ok = unsafe {
65 ffi::dynamic_store::sc_dynamic_store_add_temporary_value(
66 self.raw.as_ptr(),
67 key.as_ptr(),
68 value.as_ptr(),
69 )
70 };
71 bridge::bool_result("sc_dynamic_store_add_temporary_value", ok)
72 }
73
74 pub fn set_value(&self, key: &str, value: &PropertyList) -> Result<()> {
75 let key = bridge::cstring(key, "sc_dynamic_store_set_value")?;
76 let ok = unsafe {
77 ffi::dynamic_store::sc_dynamic_store_set_value(self.raw.as_ptr(), key.as_ptr(), value.as_ptr())
78 };
79 bridge::bool_result("sc_dynamic_store_set_value", ok)
80 }
81
82 pub fn remove_value(&self, key: &str) -> Result<()> {
83 let key = bridge::cstring(key, "sc_dynamic_store_remove_value")?;
84 let ok = unsafe { ffi::dynamic_store::sc_dynamic_store_remove_value(self.raw.as_ptr(), key.as_ptr()) };
85 bridge::bool_result("sc_dynamic_store_remove_value", ok)
86 }
87
88 pub fn notify_value(&self, key: &str) -> Result<()> {
89 let key = bridge::cstring(key, "sc_dynamic_store_notify_value")?;
90 let ok = unsafe { ffi::dynamic_store::sc_dynamic_store_notify_value(self.raw.as_ptr(), key.as_ptr()) };
91 bridge::bool_result("sc_dynamic_store_notify_value", ok)
92 }
93
94 pub fn copy_key_list(&self, pattern: &str) -> Result<Vec<String>> {
95 let pattern = bridge::cstring(pattern, "sc_dynamic_store_copy_key_list")?;
96 let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_copy_key_list(self.raw.as_ptr(), pattern.as_ptr()) };
97 Ok(bridge::take_string_array(raw))
98 }
99
100 pub fn set_notification_keys<K, P>(&self, keys: &[K], patterns: &[P]) -> Result<()>
101 where
102 K: AsRef<str>,
103 P: AsRef<str>,
104 {
105 let keys = CStringArray::new(keys, "sc_dynamic_store_set_notification_keys")?;
106 let patterns = CStringArray::new(patterns, "sc_dynamic_store_set_notification_keys")?;
107 let ok = unsafe {
108 ffi::dynamic_store::sc_dynamic_store_set_notification_keys(
109 self.raw.as_ptr(),
110 keys.as_ptr(),
111 keys.count(),
112 patterns.as_ptr(),
113 patterns.count(),
114 )
115 };
116 bridge::bool_result("sc_dynamic_store_set_notification_keys", ok)
117 }
118
119 pub fn copy_notified_keys(&self) -> Vec<String> {
120 let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_copy_notified_keys(self.raw.as_ptr()) };
121 bridge::take_string_array(raw)
122 }
123
124 pub fn computer_name(&self) -> Option<String> {
125 bridge::take_optional_string(unsafe {
126 ffi::dynamic_store::sc_dynamic_store_copy_computer_name(self.raw.as_ptr())
127 })
128 }
129
130 pub fn local_host_name(&self) -> Option<String> {
131 bridge::take_optional_string(unsafe {
132 ffi::dynamic_store::sc_dynamic_store_copy_local_host_name(self.raw.as_ptr())
133 })
134 }
135
136 pub fn location(&self) -> Option<String> {
137 bridge::take_optional_string(unsafe {
138 ffi::dynamic_store::sc_dynamic_store_copy_location(self.raw.as_ptr())
139 })
140 }
141
142 pub fn proxies(&self) -> Option<PropertyList> {
143 let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_copy_proxies(self.raw.as_ptr()) };
144 unsafe { bridge::OwnedHandle::from_raw(raw) }.map(PropertyList::from_owned_handle)
145 }
146
147 pub fn dhcp_info(&self, service_id: Option<&str>) -> Result<Option<PropertyList>> {
148 let service_id = bridge::optional_cstring(service_id, "sc_dynamic_store_copy_dhcp_info")?;
149 let raw = unsafe {
150 ffi::dynamic_store::sc_dynamic_store_copy_dhcp_info(
151 self.raw.as_ptr(),
152 service_id.as_ref().map_or(std::ptr::null(), |value| value.as_ptr()),
153 )
154 };
155 Ok(unsafe { bridge::OwnedHandle::from_raw(raw) }.map(PropertyList::from_owned_handle))
156 }
157
158 pub fn network_global_entity_key(domain: &str, entity: &str) -> Result<String> {
159 let domain = bridge::cstring(domain, "sc_dynamic_store_key_create_network_global_entity")?;
160 let entity = bridge::cstring(entity, "sc_dynamic_store_key_create_network_global_entity")?;
161 bridge::take_optional_string(unsafe {
162 ffi::dynamic_store::sc_dynamic_store_key_create_network_global_entity(
163 domain.as_ptr(),
164 entity.as_ptr(),
165 )
166 })
167 .ok_or_else(|| {
168 SystemConfigurationError::null(
169 "sc_dynamic_store_key_create_network_global_entity",
170 "bridge returned null dynamic-store global entity key",
171 )
172 })
173 }
174
175 pub fn network_interface_key(domain: &str) -> Result<String> {
176 let domain = bridge::cstring(domain, "sc_dynamic_store_key_create_network_interface")?;
177 bridge::take_optional_string(unsafe {
178 ffi::dynamic_store::sc_dynamic_store_key_create_network_interface(domain.as_ptr())
179 })
180 .ok_or_else(|| {
181 SystemConfigurationError::null(
182 "sc_dynamic_store_key_create_network_interface",
183 "bridge returned null dynamic-store interface key",
184 )
185 })
186 }
187
188 pub fn network_interface_entity_key(
189 domain: &str,
190 interface_name: &str,
191 entity: Option<&str>,
192 ) -> Result<String> {
193 let domain = bridge::cstring(domain, "sc_dynamic_store_key_create_network_interface_entity")?;
194 let interface_name = bridge::cstring(
195 interface_name,
196 "sc_dynamic_store_key_create_network_interface_entity",
197 )?;
198 let entity = bridge::optional_cstring(entity, "sc_dynamic_store_key_create_network_interface_entity")?;
199 bridge::take_optional_string(unsafe {
200 ffi::dynamic_store::sc_dynamic_store_key_create_network_interface_entity(
201 domain.as_ptr(),
202 interface_name.as_ptr(),
203 entity.as_ref().map_or(std::ptr::null(), |value| value.as_ptr()),
204 )
205 })
206 .ok_or_else(|| {
207 SystemConfigurationError::null(
208 "sc_dynamic_store_key_create_network_interface_entity",
209 "bridge returned null dynamic-store interface-entity key",
210 )
211 })
212 }
213
214 pub fn network_service_entity_key(
215 domain: &str,
216 service_id: &str,
217 entity: Option<&str>,
218 ) -> Result<String> {
219 let domain = bridge::cstring(domain, "sc_dynamic_store_key_create_network_service_entity")?;
220 let service_id = bridge::cstring(service_id, "sc_dynamic_store_key_create_network_service_entity")?;
221 let entity = bridge::optional_cstring(entity, "sc_dynamic_store_key_create_network_service_entity")?;
222 bridge::take_optional_string(unsafe {
223 ffi::dynamic_store::sc_dynamic_store_key_create_network_service_entity(
224 domain.as_ptr(),
225 service_id.as_ptr(),
226 entity.as_ref().map_or(std::ptr::null(), |value| value.as_ptr()),
227 )
228 })
229 .ok_or_else(|| {
230 SystemConfigurationError::null(
231 "sc_dynamic_store_key_create_network_service_entity",
232 "bridge returned null dynamic-store service-entity key",
233 )
234 })
235 }
236
237 pub fn computer_name_key() -> Result<String> {
238 bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_computer_name() })
239 .ok_or_else(|| {
240 SystemConfigurationError::null(
241 "sc_dynamic_store_key_create_computer_name",
242 "bridge returned null computer-name notification key",
243 )
244 })
245 }
246
247 pub fn console_user_key() -> Result<String> {
248 bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_console_user() })
249 .ok_or_else(|| {
250 SystemConfigurationError::null(
251 "sc_dynamic_store_key_create_console_user",
252 "bridge returned null console-user notification key",
253 )
254 })
255 }
256
257 pub fn host_names_key() -> Result<String> {
258 bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_host_names() })
259 .ok_or_else(|| {
260 SystemConfigurationError::null(
261 "sc_dynamic_store_key_create_host_names",
262 "bridge returned null host-names notification key",
263 )
264 })
265 }
266
267 pub fn location_key() -> Result<String> {
268 bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_location() })
269 .ok_or_else(|| {
270 SystemConfigurationError::null(
271 "sc_dynamic_store_key_create_location",
272 "bridge returned null location notification key",
273 )
274 })
275 }
276
277 pub fn proxies_key() -> Result<String> {
278 bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_proxies() })
279 .ok_or_else(|| {
280 SystemConfigurationError::null(
281 "sc_dynamic_store_key_create_proxies",
282 "bridge returned null proxies notification key",
283 )
284 })
285 }
286}