use mssf_com::FabricClient::{
IFabricServiceEndpointsVersion, IFabricServiceNotification,
IFabricServiceNotificationEventHandler, IFabricServiceNotificationEventHandler_Impl,
};
use crate::types::{ServicePartitionInformation, Uri};
use super::svc_mgmt_client::ResolvedServiceEndpoint;
pub trait ServiceNotificationEventHandler: 'static {
fn on_notification(&self, notification: ServiceNotification) -> crate::Result<()>;
}
#[derive(Debug, Clone)]
pub struct ServiceNotification {
pub service_name: Uri,
pub partition_info: Option<ServicePartitionInformation>,
pub partition_id: crate::GUID,
pub endpoints: Vec<ResolvedServiceEndpoint>,
pub version: Option<ServiceEndpointsVersion>,
}
impl From<&IFabricServiceNotification> for ServiceNotification {
fn from(com: &IFabricServiceNotification) -> Self {
let raw = unsafe { com.get_Notification().as_ref().unwrap() };
let endpoints = crate::iter::vec_from_raw_com(raw.EndpointCount as usize, raw.Endpoints);
let version = unsafe { com.GetVersion() }
.ok()
.map(ServiceEndpointsVersion::from);
Self {
service_name: Uri::from(raw.ServiceName),
partition_info: unsafe {
raw.PartitionInfo
.as_ref()
.map(ServicePartitionInformation::from)
},
partition_id: raw.PartitionId,
endpoints,
version,
}
}
}
#[derive(Debug, Clone)]
pub struct ServiceEndpointsVersion {
com: IFabricServiceEndpointsVersion,
}
impl From<IFabricServiceEndpointsVersion> for ServiceEndpointsVersion {
fn from(com: IFabricServiceEndpointsVersion) -> Self {
Self { com }
}
}
impl From<ServiceEndpointsVersion> for IFabricServiceEndpointsVersion {
fn from(value: ServiceEndpointsVersion) -> Self {
value.com
}
}
impl ServiceEndpointsVersion {
pub fn compare(&self, other: &ServiceEndpointsVersion) -> crate::Result<i32> {
unsafe { self.com.Compare(&other.com) }.map_err(crate::Error::from)
}
}
impl PartialEq for ServiceEndpointsVersion {
fn eq(&self, other: &Self) -> bool {
match self.compare(other) {
Ok(i) => i == 0,
Err(_) => false, }
}
}
impl PartialOrd for ServiceEndpointsVersion {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match self.compare(other) {
Ok(i) => Some(i.cmp(&0)),
Err(_) => None,
}
}
}
#[windows_core::implement(IFabricServiceNotificationEventHandler)]
#[allow(non_camel_case_types)] pub struct ServiceNotificationEventHandlerBridge<T>
where
T: ServiceNotificationEventHandler,
{
inner: T,
}
impl<T> ServiceNotificationEventHandlerBridge<T>
where
T: ServiceNotificationEventHandler,
{
pub fn new(inner: T) -> Self {
Self { inner }
}
pub fn new_com(inner: T) -> IFabricServiceNotificationEventHandler {
Self::new(inner).into()
}
}
impl<T> IFabricServiceNotificationEventHandler_Impl
for ServiceNotificationEventHandlerBridge_Impl<T>
where
T: ServiceNotificationEventHandler,
{
fn OnNotification(
&self,
notification: windows_core::Ref<IFabricServiceNotification>,
) -> crate::WinResult<()> {
let com = notification.unwrap();
let msg = ServiceNotification::from(com);
self.inner
.on_notification(msg)
.map_err(crate::WinError::from)
}
}
pub struct LambdaServiceNotificationHandler<T>
where
T: Fn(ServiceNotification) -> crate::Result<()> + 'static,
{
f: T,
}
impl<T> LambdaServiceNotificationHandler<T>
where
T: Fn(ServiceNotification) -> crate::Result<()> + 'static,
{
pub fn new(f: T) -> Self {
Self { f }
}
}
impl<T> ServiceNotificationEventHandler for LambdaServiceNotificationHandler<T>
where
T: Fn(ServiceNotification) -> crate::Result<()> + 'static,
{
fn on_notification(&self, notification: ServiceNotification) -> crate::Result<()> {
(self.f)(notification)
}
}