Skip to content

Commit

Permalink
server: Add DynamicService trait and adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
uklotzde committed Jan 4, 2024
1 parent 8c1d969 commit 8a943d8
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

- Server: Remove `Sync` and `Unpin` trait bounds from `Service::call()` future
result.
- Server: Add `DynamicService`/`DynamicServiceAdapter` opt-in for dynamic
dispatch.

## v0.10.0 (2024-01-03)

Expand Down
2 changes: 1 addition & 1 deletion src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub mod tcp;
pub mod rtu_over_tcp;

mod service;
pub use self::service::Service;
pub use self::service::{DynamicService, DynamicServiceAdapter, Service};

/// Cause for termination
#[derive(Debug, Clone)]
Expand Down
41 changes: 40 additions & 1 deletion src/server/service.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright (c) 2017-2024 slowtec GmbH <[email protected]>
// SPDX-License-Identifier: MIT OR Apache-2.0

use std::{future::Future, ops::Deref};
use std::{future::Future, ops::Deref, pin::Pin};

/// A Modbus server service.
pub trait Service {
Expand Down Expand Up @@ -36,3 +36,42 @@ where
self.deref().call(req)
}
}

/// A Modbus server service that uses dynamic dispatch.
pub trait DynamicService {
/// Requests handled by the service.
type Request;

/// Responses given by the service.
type Response;

/// Errors produced by the service.
type Error;

/// Process the request and return the response asynchronously.
#[allow(clippy::type_complexity)]
fn call(
&self,
req: Self::Request,
) -> Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
}

/// An adapter that allows to use a [`DynamicService`] as a [`Service`].
#[derive(Debug, Clone)]
pub struct DynamicServiceAdapter<T> {
delegate: T,
}

impl<T> Service for DynamicServiceAdapter<T>
where
T: DynamicService,
{
type Request = T::Request;
type Response = T::Response;
type Error = T::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;

fn call(&self, req: Self::Request) -> Self::Future {
self.delegate.call(req)
}
}

0 comments on commit 8a943d8

Please sign in to comment.