mssf_core/client/
notification.rs1use mssf_com::{
7 FabricClient::{
8 IFabricServiceEndpointsVersion, IFabricServiceNotification,
9 IFabricServiceNotificationEventHandler, IFabricServiceNotificationEventHandler_Impl,
10 },
11 FabricTypes::FABRIC_RESOLVED_SERVICE_ENDPOINT,
12};
13
14use crate::{
15 iter::{FabricIter, FabricListAccessor},
16 strings::WStringWrap,
17 types::ServicePartitionInformation,
18};
19
20use super::svc_mgmt_client::ResolvedServiceEndpoint;
21
22pub trait ServiceNotificationEventHandler: 'static {
25 fn on_notification(&self, notification: &ServiceNotification) -> crate::Result<()>;
26}
27
28#[derive(Debug, Clone)]
32pub struct ServiceNotification {
33 pub service_name: crate::WString,
34 pub partition_info: Option<ServicePartitionInformation>,
35 pub partition_id: crate::GUID,
36 pub endpoints: ServiceEndpointList,
37 com: IFabricServiceNotification,
38}
39
40impl From<IFabricServiceNotification> for ServiceNotification {
41 fn from(com: IFabricServiceNotification) -> Self {
42 let raw = unsafe { com.get_Notification().as_ref().unwrap() };
44 Self {
45 service_name: WStringWrap::from(crate::PCWSTR(raw.ServiceName.0)).into(),
46 partition_info: unsafe {
47 raw.PartitionInfo
51 .as_ref()
52 .map(ServicePartitionInformation::from)
53 },
54 partition_id: raw.PartitionId,
55 endpoints: ServiceEndpointList { com: com.clone() },
56 com,
57 }
58 }
59}
60
61impl ServiceNotification {
62 pub fn get_version(&self) -> crate::Result<ServiceEndpointsVersion> {
63 let version = unsafe { self.com.GetVersion() }?;
64 Ok(ServiceEndpointsVersion::from(version))
65 }
66}
67
68#[derive(Debug, Clone)]
69pub struct ServiceEndpointList {
70 com: IFabricServiceNotification,
71}
72
73impl ServiceEndpointList {
74 pub fn iter(&self) -> ServiceEndpointListIter<'_> {
76 ServiceEndpointListIter::new(self, self)
77 }
78}
79
80impl FabricListAccessor<FABRIC_RESOLVED_SERVICE_ENDPOINT> for ServiceEndpointList {
82 fn get_count(&self) -> u32 {
83 let raw = unsafe { self.com.get_Notification().as_ref().unwrap() };
84 raw.EndpointCount
85 }
86
87 fn get_first_item(&self) -> *const FABRIC_RESOLVED_SERVICE_ENDPOINT {
88 let raw = unsafe { self.com.get_Notification().as_ref().unwrap() };
89 raw.Endpoints
90 }
91}
92
93type ServiceEndpointListIter<'a> =
94 FabricIter<'a, FABRIC_RESOLVED_SERVICE_ENDPOINT, ResolvedServiceEndpoint, ServiceEndpointList>;
95
96pub struct ServiceEndpointsVersion {
98 com: IFabricServiceEndpointsVersion,
99}
100
101impl From<IFabricServiceEndpointsVersion> for ServiceEndpointsVersion {
102 fn from(com: IFabricServiceEndpointsVersion) -> Self {
103 Self { com }
104 }
105}
106
107impl From<ServiceEndpointsVersion> for IFabricServiceEndpointsVersion {
108 fn from(value: ServiceEndpointsVersion) -> Self {
109 value.com
110 }
111}
112
113impl ServiceEndpointsVersion {
114 pub fn compare(&self, other: &ServiceEndpointsVersion) -> crate::Result<i32> {
121 unsafe { self.com.Compare(&other.com) }.map_err(crate::Error::from)
122 }
123}
124
125impl PartialEq for ServiceEndpointsVersion {
126 fn eq(&self, other: &Self) -> bool {
127 match self.compare(other) {
128 Ok(i) => i == 0,
129 Err(_) => false, }
131 }
132}
133
134impl PartialOrd for ServiceEndpointsVersion {
135 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
139 match self.compare(other) {
140 Ok(i) => Some(i.cmp(&0)),
141 Err(_) => None,
143 }
144 }
145}
146
147#[windows_core::implement(IFabricServiceNotificationEventHandler)]
149#[allow(non_camel_case_types)] pub struct ServiceNotificationEventHandlerBridge<T>
151where
152 T: ServiceNotificationEventHandler,
153{
154 inner: T,
155}
156
157impl<T> ServiceNotificationEventHandlerBridge<T>
158where
159 T: ServiceNotificationEventHandler,
160{
161 pub fn new(inner: T) -> Self {
162 Self { inner }
163 }
164
165 pub fn new_com(inner: T) -> IFabricServiceNotificationEventHandler {
166 Self::new(inner).into()
167 }
168}
169
170impl<T> IFabricServiceNotificationEventHandler_Impl
171 for ServiceNotificationEventHandlerBridge_Impl<T>
172where
173 T: ServiceNotificationEventHandler,
174{
175 fn OnNotification(
176 &self,
177 notification: windows_core::Ref<IFabricServiceNotification>,
178 ) -> crate::WinResult<()> {
179 let com = notification.unwrap();
180 let msg = ServiceNotification::from(com.clone());
181 self.inner
182 .on_notification(&msg)
183 .map_err(crate::WinError::from)
184 }
185}
186
187pub struct LambdaServiceNotificationHandler<T>
192where
193 T: Fn(&ServiceNotification) -> crate::Result<()> + 'static,
194{
195 f: T,
196}
197
198impl<T> LambdaServiceNotificationHandler<T>
199where
200 T: Fn(&ServiceNotification) -> crate::Result<()> + 'static,
201{
202 pub fn new(f: T) -> Self {
203 Self { f }
204 }
205}
206
207impl<T> ServiceNotificationEventHandler for LambdaServiceNotificationHandler<T>
208where
209 T: Fn(&ServiceNotification) -> crate::Result<()> + 'static,
210{
211 fn on_notification(&self, notification: &ServiceNotification) -> crate::Result<()> {
212 (self.f)(notification)
213 }
214}