use crate::{InterfaceName, StaticRoute};
use std::error::Error;
use std::future::Future;
pub trait Driver: Send + Sync {
type Error: Error + Send + Sync + 'static;
}
pub trait Execute<Operation: Send>: Driver {
type Output: Send;
#[allow(clippy::manual_async_fn)]
fn execute<'a>(
&'a self,
operation: Operation,
) -> impl Future<Output = Result<Self::Output, Self::Error>> + Send + 'a;
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct OperationStep<Operation> {
operation: Operation,
}
pub const fn operation<Operation>(operation: Operation) -> OperationStep<Operation> {
OperationStep { operation }
}
impl<Operation> OperationStep<Operation> {
pub fn then<Next>(self, next: Next) -> Sequence<Self, Next> {
Sequence {
first: self,
second: next,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Sequence<First, Second> {
first: First,
second: Second,
}
impl<First, Second> Sequence<First, Second> {
pub fn then<Next>(self, next: Next) -> Sequence<Self, Next> {
Sequence {
first: self,
second: next,
}
}
}
pub trait Run<DriverType: Driver>: Send {
type Output: Send;
#[allow(clippy::manual_async_fn)]
fn run<'a>(
self,
driver: &'a DriverType,
) -> impl Future<Output = Result<Self::Output, DriverType::Error>> + Send + 'a
where
Self: 'a,
DriverType: 'a;
}
impl<DriverType, Operation> Run<DriverType> for OperationStep<Operation>
where
DriverType: Execute<Operation>,
Operation: Send,
{
type Output = <DriverType as Execute<Operation>>::Output;
#[allow(clippy::manual_async_fn)]
fn run<'a>(
self,
driver: &'a DriverType,
) -> impl Future<Output = Result<Self::Output, DriverType::Error>> + Send + 'a
where
Self: 'a,
DriverType: 'a,
{
async move { driver.execute(self.operation).await }
}
}
impl<DriverType, First, Second> Run<DriverType> for Sequence<First, Second>
where
DriverType: Driver,
First: Run<DriverType>,
Second: Run<DriverType>,
{
type Output = Second::Output;
#[allow(clippy::manual_async_fn)]
fn run<'a>(
self,
driver: &'a DriverType,
) -> impl Future<Output = Result<Self::Output, DriverType::Error>> + Send + 'a
where
Self: 'a,
DriverType: 'a,
{
async move {
self.first.run(driver).await?;
self.second.run(driver).await
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum AdministrativeState {
Enabled,
Disabled,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SetInterfaceState {
pub interface: InterfaceName,
pub state: AdministrativeState,
}
impl SetInterfaceState {
pub fn new(interface: InterfaceName, state: AdministrativeState) -> Self {
Self { interface, state }
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SetInterfaceDescription {
pub interface: InterfaceName,
pub description: String,
}
impl SetInterfaceDescription {
pub fn new(interface: InterfaceName, description: impl Into<String>) -> Self {
Self {
interface,
description: description.into(),
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct EnsureStaticRoute {
pub route: StaticRoute,
}
impl EnsureStaticRoute {
pub const fn new(route: StaticRoute) -> Self {
Self { route }
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct RemoveStaticRoute {
pub route: StaticRoute,
}
impl RemoveStaticRoute {
pub const fn new(route: StaticRoute) -> Self {
Self { route }
}
}