1use std::time::Duration;
7
8use crate::{
9 WString,
10 runtime::executor::BoxedCancelToken,
11 sync::{FabricReceiver, fabric_begin_end_proxy},
12 types::{NameEnumerationResult, PropertyMetadataResult, PropertyValueResult, Uri},
13};
14use mssf_com::{
15 FabricClient::{
16 IFabricNameEnumerationResult, IFabricPropertyBatchResult, IFabricPropertyEnumerationResult,
17 IFabricPropertyMetadataResult, IFabricPropertyValueResult,
18 },
19 FabricTypes::{FABRIC_PROPERTY_BATCH_OPERATION, FABRIC_PUT_CUSTOM_PROPERTY_OPERATION},
20};
21
22use mssf_com::FabricClient::IFabricPropertyManagementClient2;
23
24#[derive(Debug, Clone)]
25pub struct PropertyManagementClient {
26 com: IFabricPropertyManagementClient2,
27}
28
29impl From<IFabricPropertyManagementClient2> for PropertyManagementClient {
30 fn from(com: IFabricPropertyManagementClient2) -> Self {
31 Self { com }
32 }
33}
34
35impl From<PropertyManagementClient> for IFabricPropertyManagementClient2 {
36 fn from(value: PropertyManagementClient) -> Self {
37 value.com
38 }
39}
40
41impl PropertyManagementClient {
42 fn create_name_internal(
43 &self,
44 name: &Uri,
45 timeout_milliseconds: u32,
46 cancellation_token: Option<BoxedCancelToken>,
47 ) -> FabricReceiver<crate::Result<()>> {
48 let com1 = &self.com;
49 let com2 = self.com.clone();
50 fabric_begin_end_proxy(
51 move |callback| unsafe {
52 com1.BeginCreateName(name.as_raw(), timeout_milliseconds, callback)
53 },
54 move |ctx| unsafe { com2.EndCreateName(ctx) },
55 cancellation_token,
56 )
57 }
58
59 fn delete_name_internal(
60 &self,
61 name: &Uri,
62 timeout_milliseconds: u32,
63 cancellation_token: Option<BoxedCancelToken>,
64 ) -> FabricReceiver<crate::Result<()>> {
65 let com1 = &self.com;
66 let com2 = self.com.clone();
67 fabric_begin_end_proxy(
68 move |callback| unsafe {
69 com1.BeginDeleteName(name.as_raw(), timeout_milliseconds, callback)
70 },
71 move |ctx| unsafe { com2.EndDeleteName(ctx) },
72 cancellation_token,
73 )
74 }
75
76 fn name_exists_internal(
77 &self,
78 name: &Uri,
79 timeout_milliseconds: u32,
80 cancellation_token: Option<BoxedCancelToken>,
81 ) -> FabricReceiver<crate::Result<u8>> {
82 let com1 = &self.com;
83 let com2 = self.com.clone();
84 fabric_begin_end_proxy(
85 move |callback| unsafe {
86 com1.BeginNameExists(name.as_raw(), timeout_milliseconds, callback)
87 },
88 move |ctx| unsafe { com2.EndNameExists(ctx) },
89 cancellation_token,
90 )
91 }
92
93 fn enumerate_sub_names_internal(
94 &self,
95 name: &Uri,
96 prev: Option<&IFabricNameEnumerationResult>,
97 recursive: bool,
98 timeout_milliseconds: u32,
99 cancellation_token: Option<BoxedCancelToken>,
100 ) -> FabricReceiver<crate::Result<IFabricNameEnumerationResult>> {
101 let com1 = &self.com;
102 let com2 = self.com.clone();
103 fabric_begin_end_proxy(
104 move |callback| unsafe {
105 com1.BeginEnumerateSubNames(
106 name.as_raw(),
107 prev,
108 recursive,
109 timeout_milliseconds,
110 callback,
111 )
112 },
113 move |ctx| unsafe { com2.EndEnumerateSubNames(ctx) },
114 cancellation_token,
115 )
116 }
117
118 fn put_property_binary_internal(
119 &self,
120 name: &Uri,
121 property_name: &WString,
122 data: &[u8],
123 timeout_milliseconds: u32,
124 cancellation_token: Option<BoxedCancelToken>,
125 ) -> FabricReceiver<crate::Result<()>> {
126 let com1 = &self.com;
127 let com2 = self.com.clone();
128 fabric_begin_end_proxy(
129 move |callback| unsafe {
130 com1.BeginPutPropertyBinary(
131 name.as_raw(),
132 property_name.as_pcwstr(),
133 data,
134 timeout_milliseconds,
135 callback,
136 )
137 },
138 move |ctx| unsafe { com2.EndPutPropertyBinary(ctx) },
139 cancellation_token,
140 )
141 }
142
143 fn put_property_int64_internal(
144 &self,
145 name: &Uri,
146 property_name: &WString,
147 data: i64,
148 timeout_milliseconds: u32,
149 cancellation_token: Option<BoxedCancelToken>,
150 ) -> FabricReceiver<crate::Result<()>> {
151 let com1 = &self.com;
152 let com2 = self.com.clone();
153 fabric_begin_end_proxy(
154 move |callback| unsafe {
155 com1.BeginPutPropertyInt64(
156 name.as_raw(),
157 property_name.as_pcwstr(),
158 data,
159 timeout_milliseconds,
160 callback,
161 )
162 },
163 move |ctx| unsafe { com2.EndPutPropertyInt64(ctx) },
164 cancellation_token,
165 )
166 }
167
168 fn put_property_double_internal(
169 &self,
170 name: &Uri,
171 property_name: &WString,
172 data: f64,
173 timeout_milliseconds: u32,
174 cancellation_token: Option<BoxedCancelToken>,
175 ) -> FabricReceiver<crate::Result<()>> {
176 let com1 = &self.com;
177 let com2 = self.com.clone();
178 fabric_begin_end_proxy(
179 move |callback| unsafe {
180 com1.BeginPutPropertyDouble(
181 name.as_raw(),
182 property_name.as_pcwstr(),
183 data,
184 timeout_milliseconds,
185 callback,
186 )
187 },
188 move |ctx| unsafe { com2.EndPutPropertyDouble(ctx) },
189 cancellation_token,
190 )
191 }
192
193 fn put_property_wstring_internal(
194 &self,
195 name: &Uri,
196 property_name: &WString,
197 data: &WString,
198 timeout_milliseconds: u32,
199 cancellation_token: Option<BoxedCancelToken>,
200 ) -> FabricReceiver<crate::Result<()>> {
201 let com1 = &self.com;
202 let com2 = self.com.clone();
203 fabric_begin_end_proxy(
204 move |callback| unsafe {
205 com1.BeginPutPropertyWString(
206 name.as_raw(),
207 property_name.as_pcwstr(),
208 data.as_pcwstr(),
209 timeout_milliseconds,
210 callback,
211 )
212 },
213 move |ctx| unsafe { com2.EndPutPropertyWString(ctx) },
214 cancellation_token,
215 )
216 }
217
218 fn put_property_guid_internal(
219 &self,
220 name: &Uri,
221 property_name: &WString,
222 data: &windows_core::GUID,
223 timeout_milliseconds: u32,
224 cancellation_token: Option<BoxedCancelToken>,
225 ) -> FabricReceiver<crate::Result<()>> {
226 let com1 = &self.com;
227 let com2 = self.com.clone();
228 fabric_begin_end_proxy(
229 move |callback| unsafe {
230 com1.BeginPutPropertyGuid(
231 name.as_raw(),
232 property_name.as_pcwstr(),
233 data,
234 timeout_milliseconds,
235 callback,
236 )
237 },
238 move |ctx| unsafe { com2.EndPutPropertyGuid(ctx) },
239 cancellation_token,
240 )
241 }
242
243 fn delete_property_internal(
244 &self,
245 name: &Uri,
246 property_name: &WString,
247 timeout_milliseconds: u32,
248 cancellation_token: Option<BoxedCancelToken>,
249 ) -> FabricReceiver<crate::Result<()>> {
250 let com1 = &self.com;
251 let com2 = self.com.clone();
252 fabric_begin_end_proxy(
253 move |callback| unsafe {
254 com1.BeginDeleteProperty(
255 name.as_raw(),
256 property_name.as_pcwstr(),
257 timeout_milliseconds,
258 callback,
259 )
260 },
261 move |ctx| unsafe { com2.EndDeleteProperty(ctx) },
262 cancellation_token,
263 )
264 }
265
266 fn get_property_metadata_internal(
267 &self,
268 name: &Uri,
269 property_name: &WString,
270 timeout_milliseconds: u32,
271 cancellation_token: Option<BoxedCancelToken>,
272 ) -> FabricReceiver<crate::Result<IFabricPropertyMetadataResult>> {
273 let com1 = &self.com;
274 let com2 = self.com.clone();
275 fabric_begin_end_proxy(
276 move |callback| unsafe {
277 com1.BeginGetPropertyMetadata(
278 name.as_raw(),
279 property_name.as_pcwstr(),
280 timeout_milliseconds,
281 callback,
282 )
283 },
284 move |ctx| unsafe { com2.EndGetPropertyMetadata(ctx) },
285 cancellation_token,
286 )
287 }
288
289 fn get_property_internal(
290 &self,
291 name: &Uri,
292 property_name: &WString,
293 timeout_milliseconds: u32,
294 cancellation_token: Option<BoxedCancelToken>,
295 ) -> FabricReceiver<crate::Result<IFabricPropertyValueResult>> {
296 let com1 = &self.com;
297 let com2 = self.com.clone();
298 fabric_begin_end_proxy(
299 move |callback| unsafe {
300 com1.BeginGetProperty(
301 name.as_raw(),
302 property_name.as_pcwstr(),
303 timeout_milliseconds,
304 callback,
305 )
306 },
307 move |ctx| unsafe { com2.EndGetProperty(ctx) },
308 cancellation_token,
309 )
310 }
311
312 #[allow(dead_code)]
315 fn submit_property_batch_internal(
316 &self,
317 name: &Uri,
318 batch: &[FABRIC_PROPERTY_BATCH_OPERATION],
319 timeout_milliseconds: u32,
320 cancellation_token: Option<BoxedCancelToken>,
321 ) -> FabricReceiver<crate::Result<(u32, IFabricPropertyBatchResult)>> {
322 let com1 = &self.com;
323 let com2 = self.com.clone();
324 fabric_begin_end_proxy(
325 move |callback| unsafe {
326 com1.BeginSubmitPropertyBatch(name.as_raw(), batch, timeout_milliseconds, callback)
327 },
328 move |ctx| unsafe {
329 let mut failed_operation_index_in_request = 0;
330 let result =
331 com2.EndSubmitPropertyBatch(ctx, &mut failed_operation_index_in_request);
332 result.map(|res| (failed_operation_index_in_request, res))
333 },
334 cancellation_token,
335 )
336 }
337
338 #[allow(dead_code)]
340 fn enumerate_properties_internal(
341 &self,
342 name: &Uri,
343 include_values: bool,
344 prev: Option<&IFabricPropertyEnumerationResult>,
345 timeout_milliseconds: u32,
346 cancellation_token: Option<BoxedCancelToken>,
347 ) -> FabricReceiver<crate::Result<IFabricPropertyEnumerationResult>> {
348 let com1 = &self.com;
349 let com2 = self.com.clone();
350 fabric_begin_end_proxy(
351 move |callback| unsafe {
352 com1.BeginEnumerateProperties(
353 name.as_raw(),
354 include_values,
355 prev,
356 timeout_milliseconds,
357 callback,
358 )
359 },
360 move |ctx| unsafe { com2.EndEnumerateProperties(ctx) },
361 cancellation_token,
362 )
363 }
364
365 #[allow(dead_code)]
367 fn put_custom_property_operation_internal(
368 &self,
369 name: &Uri,
370 property_operation: &FABRIC_PUT_CUSTOM_PROPERTY_OPERATION,
371 timeout_milliseconds: u32,
372 cancellation_token: Option<BoxedCancelToken>,
373 ) -> FabricReceiver<crate::Result<()>> {
374 let com1 = &self.com;
375 let com2 = self.com.clone();
376 fabric_begin_end_proxy(
377 move |callback| unsafe {
378 com1.BeginPutCustomPropertyOperation(
379 name.as_raw(),
380 property_operation,
381 timeout_milliseconds,
382 callback,
383 )
384 },
385 move |ctx| unsafe { com2.EndPutCustomPropertyOperation(ctx) },
386 cancellation_token,
387 )
388 }
389}
390
391impl PropertyManagementClient {
392 pub async fn create_name(
400 &self,
401 name: &Uri,
402 timeout: Duration,
403 cancellation_token: Option<BoxedCancelToken>,
404 ) -> crate::Result<()> {
405 self.create_name_internal(
406 name,
407 timeout.as_millis().try_into().unwrap(),
408 cancellation_token,
409 )
410 .await??;
411 Ok(())
412 }
413
414 pub async fn delete_name(
418 &self,
419 name: &Uri,
420 timeout: Duration,
421 cancellation_token: Option<BoxedCancelToken>,
422 ) -> crate::Result<()> {
423 self.delete_name_internal(
424 name,
425 timeout.as_millis().try_into().unwrap(),
426 cancellation_token,
427 )
428 .await??;
429 Ok(())
430 }
431
432 pub async fn name_exists(
434 &self,
435 name: &Uri,
436 timeout: Duration,
437 cancellation_token: Option<BoxedCancelToken>,
438 ) -> crate::Result<bool> {
439 self.name_exists_internal(
440 name,
441 timeout.as_millis().try_into().unwrap(),
442 cancellation_token,
443 )
444 .await?
445 .map(|exist| exist != 0)
446 }
447
448 pub async fn enumerate_sub_names(
453 &self,
454 name: &Uri,
455 prev: Option<&NameEnumerationResult>,
456 recursive: bool,
457 timeout: Duration,
458 cancellation_token: Option<BoxedCancelToken>,
459 ) -> crate::Result<NameEnumerationResult> {
460 self.enumerate_sub_names_internal(
461 name,
462 prev.map(|x| x.as_com()),
463 recursive,
464 timeout.as_millis().try_into().unwrap(),
465 cancellation_token,
466 )
467 .await?
468 .map(NameEnumerationResult::from_com)
469 }
470
471 pub async fn put_property_binary(
473 &self,
474 name: &Uri,
475 property_name: &WString,
476 data: &[u8],
477 timeout: Duration,
478 cancellation_token: Option<BoxedCancelToken>,
479 ) -> crate::Result<()> {
480 self.put_property_binary_internal(
481 name,
482 property_name,
483 data,
484 timeout.as_millis().try_into().unwrap(),
485 cancellation_token,
486 )
487 .await??;
488 Ok(())
489 }
490
491 pub async fn put_property_double(
493 &self,
494 name: &Uri,
495 property_name: &WString,
496 data: f64,
497 timeout: Duration,
498 cancellation_token: Option<BoxedCancelToken>,
499 ) -> crate::Result<()> {
500 self.put_property_double_internal(
501 name,
502 property_name,
503 data,
504 timeout.as_millis().try_into().unwrap(),
505 cancellation_token,
506 )
507 .await??;
508 Ok(())
509 }
510
511 pub async fn put_property_int64(
513 &self,
514 name: &Uri,
515 property_name: &WString,
516 data: i64,
517 timeout: Duration,
518 cancellation_token: Option<BoxedCancelToken>,
519 ) -> crate::Result<()> {
520 self.put_property_int64_internal(
521 name,
522 property_name,
523 data,
524 timeout.as_millis().try_into().unwrap(),
525 cancellation_token,
526 )
527 .await??;
528 Ok(())
529 }
530
531 pub async fn put_property_wstring(
533 &self,
534 name: &Uri,
535 property_name: &WString,
536 data: &WString,
537 timeout: Duration,
538 cancellation_token: Option<BoxedCancelToken>,
539 ) -> crate::Result<()> {
540 self.put_property_wstring_internal(
541 name,
542 property_name,
543 data,
544 timeout.as_millis().try_into().unwrap(),
545 cancellation_token,
546 )
547 .await??;
548 Ok(())
549 }
550
551 pub async fn put_property_guid(
553 &self,
554 name: &Uri,
555 property_name: &WString,
556 data: &windows_core::GUID,
557 timeout: Duration,
558 cancellation_token: Option<BoxedCancelToken>,
559 ) -> crate::Result<()> {
560 self.put_property_guid_internal(
561 name,
562 property_name,
563 data,
564 timeout.as_millis().try_into().unwrap(),
565 cancellation_token,
566 )
567 .await??;
568 Ok(())
569 }
570
571 pub async fn delete_property(
573 &self,
574 name: &Uri,
575 property_name: &WString,
576 timeout: Duration,
577 cancellation_token: Option<BoxedCancelToken>,
578 ) -> crate::Result<()> {
579 self.delete_property_internal(
580 name,
581 property_name,
582 timeout.as_millis().try_into().unwrap(),
583 cancellation_token,
584 )
585 .await??;
586 Ok(())
587 }
588
589 pub async fn get_property_metadata(
591 &self,
592 name: &Uri,
593 property_name: &WString,
594 timeout: Duration,
595 cancellation_token: Option<BoxedCancelToken>,
596 ) -> crate::Result<PropertyMetadataResult> {
597 self.get_property_metadata_internal(
598 name,
599 property_name,
600 timeout.as_millis().try_into().unwrap(),
601 cancellation_token,
602 )
603 .await?
604 .map(PropertyMetadataResult::from_com)
605 }
606
607 pub async fn get_property(
609 &self,
610 name: &Uri,
611 property_name: &WString,
612 timeout: Duration,
613 cancellation_token: Option<BoxedCancelToken>,
614 ) -> crate::Result<PropertyValueResult> {
615 self.get_property_internal(
616 name,
617 property_name,
618 timeout.as_millis().try_into().unwrap(),
619 cancellation_token,
620 )
621 .await?
622 .map(PropertyValueResult::from_com)
623 }
624}