1#![allow(non_camel_case_types)]
8
9use std::sync::Arc;
10
11use crate::{
12 ErrorCode, runtime::SelfReconfiguringServicePartition, strings::StringResult,
13 sync::BridgeContext, types::Uri,
14};
15use mssf_com::{
16 FabricCommon::IFabricStringResult,
17 FabricRuntime::{
18 IFabricSelfReconfiguringConfigurationChangeRequest, IFabricSelfReconfiguringServiceFactory,
19 IFabricSelfReconfiguringServiceFactory_Impl, IFabricSelfReconfiguringServiceInstance,
20 IFabricSelfReconfiguringServiceInstance_Impl, IFabricSelfReconfiguringServicePartition,
21 },
22 FabricTypes::{
23 FABRIC_SELF_RECONFIGURING_CONFIGURATION_REQUEST,
24 FABRIC_SELF_RECONFIGURING_INSTANCE_OPEN_MODE, FABRIC_URI,
25 },
26};
27use windows_core::{WString, implement};
28
29use crate::runtime::{
30 executor::Executor,
31 {ISelfReconfiguringServiceFactory, ISelfReconfiguringServiceInstance},
32};
33use crate::types::{
34 SelfReconfiguringConfigurationChangeRequest, SelfReconfiguringConfigurationRequest,
35 SelfReconfiguringOpenMode,
36};
37
38#[implement(IFabricSelfReconfiguringServiceFactory)]
39pub struct SelfReconfiguringServiceFactoryBridge<E>
40where
41 E: Executor + 'static,
42{
43 inner: Box<dyn ISelfReconfiguringServiceFactory>,
44 rt: E,
45}
46
47impl<E> SelfReconfiguringServiceFactoryBridge<E>
48where
49 E: Executor,
50{
51 pub fn create(
52 factory: Box<dyn ISelfReconfiguringServiceFactory>,
53 rt: E,
54 ) -> SelfReconfiguringServiceFactoryBridge<E> {
55 SelfReconfiguringServiceFactoryBridge { inner: factory, rt }
56 }
57}
58
59impl<E> IFabricSelfReconfiguringServiceFactory_Impl
60 for SelfReconfiguringServiceFactoryBridge_Impl<E>
61where
62 E: Executor,
63{
64 #[allow(clippy::not_unsafe_ptr_arg_deref)]
65 #[cfg_attr(
66 feature = "tracing",
67 tracing::instrument(skip_all, ret(level = "debug"), err)
68 )]
69 fn CreateInstance(
70 &self,
71 servicetypename: &crate::PCWSTR,
72 servicename: FABRIC_URI,
73 initializationdatalength: u32,
74 initializationdata: *const u8,
75 partitionid: &crate::GUID,
76 instanceid: i64,
77 ) -> crate::WinResult<IFabricSelfReconfiguringServiceInstance> {
78 let h_servicename = Uri::from(servicename);
79 let h_servicetypename = WString::from(*servicetypename);
80 let data = unsafe {
81 if !initializationdata.is_null() {
82 std::slice::from_raw_parts(initializationdata, initializationdatalength as usize)
83 } else {
84 &[]
85 }
86 };
87
88 let instance = self.inner.create_instance(
89 h_servicetypename,
90 h_servicename,
91 data,
92 *partitionid,
93 instanceid,
94 )?;
95 let rt = self.rt.clone();
96 let instance_bridge = IFabricSelfReconfiguringServiceInstanceBridge::create(instance, rt);
97
98 Ok(instance_bridge.into())
99 }
100}
101
102#[implement(IFabricSelfReconfiguringServiceInstance)]
104pub(crate) struct IFabricSelfReconfiguringServiceInstanceBridge<E>
105where
106 E: Executor,
107{
108 inner: Arc<Box<dyn ISelfReconfiguringServiceInstance>>,
109 rt: E,
110}
111
112impl<E> IFabricSelfReconfiguringServiceInstanceBridge<E>
113where
114 E: Executor,
115{
116 pub fn create(
117 instance: Box<dyn ISelfReconfiguringServiceInstance>,
118 rt: E,
119 ) -> IFabricSelfReconfiguringServiceInstanceBridge<E> {
120 IFabricSelfReconfiguringServiceInstanceBridge {
121 inner: Arc::new(instance),
122 rt,
123 }
124 }
125}
126
127impl<E> IFabricSelfReconfiguringServiceInstance_Impl
128 for IFabricSelfReconfiguringServiceInstanceBridge_Impl<E>
129where
130 E: Executor,
131{
132 #[cfg_attr(
133 feature = "tracing",
134 tracing::instrument(skip_all, ret(level = "debug"), err)
135 )]
136 fn BeginOpen(
137 &self,
138 openmode: FABRIC_SELF_RECONFIGURING_INSTANCE_OPEN_MODE,
139 partition: windows_core::Ref<IFabricSelfReconfiguringServicePartition>,
140 callback: windows_core::Ref<super::IFabricAsyncOperationCallback>,
141 ) -> crate::WinResult<super::IFabricAsyncOperationContext> {
142 let partition_cp = partition.unwrap().clone();
143 let partition_bridge = SelfReconfiguringServicePartition::new(partition_cp);
144 let open_mode = SelfReconfiguringOpenMode::from(openmode);
145 let inner = self.inner.clone();
146 let (ctx, token) = BridgeContext::make(callback);
147 ctx.spawn(&self.rt, async move {
148 inner
149 .open(Arc::new(partition_bridge), open_mode, token)
150 .await
151 .map(|s| IFabricStringResult::from(StringResult::new(s)))
152 .map_err(crate::WinError::from)
153 })
154 }
155
156 #[cfg_attr(
157 feature = "tracing",
158 tracing::instrument(skip_all, ret(level = "debug"), err)
159 )]
160 fn EndOpen(
161 &self,
162 context: windows_core::Ref<super::IFabricAsyncOperationContext>,
163 ) -> crate::WinResult<IFabricStringResult> {
164 BridgeContext::result(context)?
165 }
166
167 #[allow(clippy::not_unsafe_ptr_arg_deref)]
168 #[cfg_attr(
169 feature = "tracing",
170 tracing::instrument(skip_all, ret(level = "debug"), err)
171 )]
172 fn RequestConfiguration(
173 &self,
174 configurationrequest: *const FABRIC_SELF_RECONFIGURING_CONFIGURATION_REQUEST,
175 ) -> crate::WinResult<()> {
176 if configurationrequest.is_null() {
177 return Err(ErrorCode::E_POINTER.into());
178 }
179 let request =
180 SelfReconfiguringConfigurationRequest::from(unsafe { &*configurationrequest });
181 self.inner
182 .request_configuration(request)
183 .map_err(crate::WinError::from)
184 }
185
186 #[cfg_attr(
187 feature = "tracing",
188 tracing::instrument(skip_all, ret(level = "debug"), err)
189 )]
190 fn RequestConfigurationChange(
191 &self,
192 configurationchangerequest: windows_core::Ref<
193 IFabricSelfReconfiguringConfigurationChangeRequest,
194 >,
195 ) -> crate::WinResult<()> {
196 let com = configurationchangerequest.ok()?;
197 let raw = unsafe { com.get_ConfigurationChangeRequest() };
198 if raw.is_null() {
199 return Err(ErrorCode::E_POINTER.into());
200 }
201 let change = SelfReconfiguringConfigurationChangeRequest::from(unsafe { &*raw });
202 self.inner
203 .request_configuration_change(change)
204 .map_err(crate::WinError::from)
205 }
206
207 #[cfg_attr(
208 feature = "tracing",
209 tracing::instrument(skip_all, ret(level = "debug"), err)
210 )]
211 fn BeginClose(
212 &self,
213 callback: windows_core::Ref<super::IFabricAsyncOperationCallback>,
214 ) -> crate::WinResult<super::IFabricAsyncOperationContext> {
215 let inner = self.inner.clone();
216 let (ctx, token) = BridgeContext::make(callback);
217 ctx.spawn(&self.rt, async move {
218 inner.close(token).await.map_err(crate::WinError::from)
219 })
220 }
221
222 #[cfg_attr(
223 feature = "tracing",
224 tracing::instrument(skip_all, ret(level = "debug"), err)
225 )]
226 fn EndClose(
227 &self,
228 context: windows_core::Ref<super::IFabricAsyncOperationContext>,
229 ) -> crate::WinResult<()> {
230 BridgeContext::result(context)?
231 }
232
233 #[cfg_attr(
234 feature = "tracing",
235 tracing::instrument(skip_all, ret(level = "debug"))
236 )]
237 fn Abort(&self) {
238 self.inner.abort()
239 }
240}