From 9541d3cac0e53b8216453265df735c8a47ba8197 Mon Sep 17 00:00:00 2001 From: jadamcrain Date: Mon, 20 May 2024 15:33:36 -0700 Subject: [PATCH] move Promise into its own module --- dnp3/src/master/association.rs | 3 ++- dnp3/src/master/extract.rs | 2 +- dnp3/src/master/handler.rs | 27 +--------------------- dnp3/src/master/messages.rs | 2 +- dnp3/src/master/mod.rs | 1 + dnp3/src/master/poll.rs | 3 ++- dnp3/src/master/promise.rs | 25 ++++++++++++++++++++ dnp3/src/master/tasks/command.rs | 2 +- dnp3/src/master/tasks/deadbands.rs | 3 ++- dnp3/src/master/tasks/empty_response.rs | 3 ++- dnp3/src/master/tasks/file/authenticate.rs | 3 ++- dnp3/src/master/tasks/file/close.rs | 3 ++- dnp3/src/master/tasks/file/directory.rs | 3 ++- dnp3/src/master/tasks/file/get_info.rs | 3 ++- dnp3/src/master/tasks/file/open.rs | 3 ++- dnp3/src/master/tasks/file/write_block.rs | 3 ++- dnp3/src/master/tasks/mod.rs | 2 +- dnp3/src/master/tasks/read.rs | 2 +- dnp3/src/master/tasks/restart.rs | 2 +- dnp3/src/master/tasks/time.rs | 2 +- dnp3/src/master/tests/harness/mod.rs | 4 ++-- 21 files changed, 56 insertions(+), 45 deletions(-) create mode 100644 dnp3/src/master/promise.rs diff --git a/dnp3/src/master/association.rs b/dnp3/src/master/association.rs index 0987a84f..5cebffdd 100644 --- a/dnp3/src/master/association.rs +++ b/dnp3/src/master/association.rs @@ -11,7 +11,7 @@ use crate::app::{Sequence, Timeout}; use crate::link::EndpointAddress; use crate::master::error::{AssociationError, TaskError, TimeSyncError}; use crate::master::extract::extract_measurements; -use crate::master::handler::{AssociationHandler, Promise}; +use crate::master::handler::AssociationHandler; use crate::master::messages::AssociationMsgType; use crate::master::poll::{PollHandle, PollMap, PollMsg}; use crate::master::request::{Classes, EventClasses, TimeSyncProcedure}; @@ -22,6 +22,7 @@ use crate::master::tasks::{AppTask, AssociationTask, ReadTask, Task}; use crate::master::{AssociationInformation, ReadHandler, ReadType, TaskType}; use crate::util::Smallest; +use crate::master::promise::Promise; use crate::transport::FragmentAddr; use crate::util::session::RunError; use tokio::time::Instant; diff --git a/dnp3/src/master/extract.rs b/dnp3/src/master/extract.rs index 13d7f6e2..22651094 100644 --- a/dnp3/src/master/extract.rs +++ b/dnp3/src/master/extract.rs @@ -91,7 +91,7 @@ mod test { use crate::app::control::CommandStatus; use crate::app::parse::parser::HeaderCollection; use crate::app::*; - use crate::master::handler::{HeaderInfo, ReadHandler}; + use crate::master::{HeaderInfo, ReadHandler}; use super::*; diff --git a/dnp3/src/master/handler.rs b/dnp3/src/master/handler.rs index f3b9b6da..8a5cc1db 100644 --- a/dnp3/src/master/handler.rs +++ b/dnp3/src/master/handler.rs @@ -10,6 +10,7 @@ use crate::master::association::AssociationConfig; use crate::master::error::{AssociationError, CommandError, PollError, TaskError, TimeSyncError}; use crate::master::messages::{AssociationMsg, AssociationMsgType, MasterMsg, Message}; use crate::master::poll::{PollHandle, PollMsg}; +use crate::master::promise::Promise; use crate::master::request::{CommandHeaders, CommandMode, ReadRequest, TimeSyncProcedure}; use crate::master::tasks::command::CommandTask; use crate::master::tasks::deadbands::WriteDeadBandsTask; @@ -531,32 +532,6 @@ impl AssociationHandle { } } -/// A generic callback type that must be invoked once and only once. -/// The user can select to implement it using FnOnce or a -/// one-shot reply channel -pub(crate) enum Promise { - /// nothing happens when the promise is completed - None, - /// one-shot reply channel is consumed when the promise is completed - OneShot(tokio::sync::oneshot::Sender), -} - -impl Promise { - pub(crate) fn one_shot() -> (Self, tokio::sync::oneshot::Receiver) { - let (tx, rx) = tokio::sync::oneshot::channel(); - (Self::OneShot(tx), rx) - } - - pub(crate) fn complete(self, value: T) { - match self { - Promise::None => {} - Promise::OneShot(s) => { - s.send(value).ok(); - } - } - } -} - /// Task types used in [`AssociationInformation`] #[cfg_attr(not(feature = "ffi"), non_exhaustive)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] diff --git a/dnp3/src/master/messages.rs b/dnp3/src/master/messages.rs index c989e9fd..b3d16fab 100644 --- a/dnp3/src/master/messages.rs +++ b/dnp3/src/master/messages.rs @@ -3,8 +3,8 @@ use crate::decode::DecodeLevel; use crate::link::EndpointAddress; use crate::master::error::PollError; use crate::master::error::{AssociationError, TaskError}; -use crate::master::handler::Promise; use crate::master::poll::PollMsg; +use crate::master::promise::Promise; use crate::master::tasks::Task; use crate::master::{AssociationConfig, AssociationHandler, AssociationInformation, ReadHandler}; use crate::transport::FragmentAddr; diff --git a/dnp3/src/master/mod.rs b/dnp3/src/master/mod.rs index 23288f4b..e410bbf8 100644 --- a/dnp3/src/master/mod.rs +++ b/dnp3/src/master/mod.rs @@ -17,6 +17,7 @@ pub(crate) mod convert; pub(crate) mod extract; pub(crate) mod messages; pub(crate) mod poll; +pub(crate) mod promise; pub(crate) mod task; pub(crate) mod tasks; diff --git a/dnp3/src/master/poll.rs b/dnp3/src/master/poll.rs index a017501e..194a6c32 100644 --- a/dnp3/src/master/poll.rs +++ b/dnp3/src/master/poll.rs @@ -5,10 +5,11 @@ use crate::app::format::write::HeaderWriter; use crate::app::Shutdown; use crate::master::association::Next; use crate::master::error::PollError; -use crate::master::handler::{AssociationHandle, Promise}; +use crate::master::handler::AssociationHandle; use crate::master::request::ReadRequest; use crate::util::Smallest; +use crate::master::promise::Promise; use tokio::time::Instant; /// Periodic poll representation diff --git a/dnp3/src/master/promise.rs b/dnp3/src/master/promise.rs new file mode 100644 index 00000000..e949c500 --- /dev/null +++ b/dnp3/src/master/promise.rs @@ -0,0 +1,25 @@ +/// A generic callback type that must be invoked once and only once. +/// The user can select to implement it using FnOnce or a +/// one-shot reply channel +pub(crate) enum Promise { + /// nothing happens when the promise is completed + None, + /// one-shot reply channel is consumed when the promise is completed + OneShot(tokio::sync::oneshot::Sender), +} + +impl Promise { + pub(crate) fn one_shot() -> (Self, tokio::sync::oneshot::Receiver) { + let (tx, rx) = tokio::sync::oneshot::channel(); + (Self::OneShot(tx), rx) + } + + pub(crate) fn complete(self, value: T) { + match self { + Promise::None => {} + Promise::OneShot(s) => { + s.send(value).ok(); + } + } + } +} diff --git a/dnp3/src/master/tasks/command.rs b/dnp3/src/master/tasks/command.rs index aedb9e1c..1cfc9d9b 100644 --- a/dnp3/src/master/tasks/command.rs +++ b/dnp3/src/master/tasks/command.rs @@ -2,7 +2,7 @@ use crate::app::format::write::HeaderWriter; use crate::app::parse::parser::{HeaderCollection, Response}; use crate::app::FunctionCode; use crate::master::error::{CommandError, CommandResponseError, TaskError}; -use crate::master::handler::Promise; +use crate::master::promise::Promise; use crate::master::request::*; use crate::master::tasks::{AppTask, NonReadTask, Task}; diff --git a/dnp3/src/master/tasks/deadbands.rs b/dnp3/src/master/tasks/deadbands.rs index 3104876a..39d4868e 100644 --- a/dnp3/src/master/tasks/deadbands.rs +++ b/dnp3/src/master/tasks/deadbands.rs @@ -1,8 +1,9 @@ use crate::app::format::write::HeaderWriter; use crate::app::parse::parser::Response; use crate::app::FunctionCode; +use crate::master::promise::Promise; use crate::master::tasks::{AppTask, NonReadTask, Task}; -use crate::master::{DeadBandHeader, DeadBandHeaderVariants, Promise, TaskError, WriteError}; +use crate::master::{DeadBandHeader, DeadBandHeaderVariants, TaskError, WriteError}; pub(crate) struct WriteDeadBandsTask { headers: Vec, diff --git a/dnp3/src/master/tasks/empty_response.rs b/dnp3/src/master/tasks/empty_response.rs index f5c58585..bafc77ec 100644 --- a/dnp3/src/master/tasks/empty_response.rs +++ b/dnp3/src/master/tasks/empty_response.rs @@ -1,8 +1,9 @@ use crate::app::format::write::HeaderWriter; use crate::app::parse::parser::Response; use crate::app::FunctionCode; +use crate::master::promise::Promise; use crate::master::tasks::{AppTask, NonReadTask, Task}; -use crate::master::{Headers, Promise, TaskError, WriteError}; +use crate::master::{Headers, TaskError, WriteError}; pub(crate) struct EmptyResponseTask { function: FunctionCode, diff --git a/dnp3/src/master/tasks/file/authenticate.rs b/dnp3/src/master/tasks/file/authenticate.rs index 0b7bfcc9..97a009dc 100644 --- a/dnp3/src/master/tasks/file/authenticate.rs +++ b/dnp3/src/master/tasks/file/authenticate.rs @@ -3,8 +3,9 @@ use crate::app::format::WriteError; use crate::app::parse::free_format::FreeFormatVariation; use crate::app::parse::parser::{HeaderDetails, Response}; use crate::app::{FunctionCode, Group70Var2}; +use crate::master::promise::Promise; use crate::master::tasks::{AppTask, NonReadTask, Task}; -use crate::master::{AuthKey, FileCredentials, FileError, Promise, TaskError}; +use crate::master::{AuthKey, FileCredentials, FileError, TaskError}; pub(crate) struct AuthFileTask { pub(crate) credentials: FileCredentials, diff --git a/dnp3/src/master/tasks/file/close.rs b/dnp3/src/master/tasks/file/close.rs index 89d53157..76703f82 100644 --- a/dnp3/src/master/tasks/file/close.rs +++ b/dnp3/src/master/tasks/file/close.rs @@ -3,9 +3,10 @@ use crate::app::format::WriteError; use crate::app::parse::free_format::FreeFormatVariation; use crate::app::parse::parser::{HeaderDetails, Response}; use crate::app::{FileStatus, FunctionCode, Group70Var4}; +use crate::master::promise::Promise; use crate::master::tasks::file::REQUEST_ID; use crate::master::tasks::{AppTask, NonReadTask, Task}; -use crate::master::{FileError, FileHandle, Promise, TaskError}; +use crate::master::{FileError, FileHandle, TaskError}; pub(crate) struct CloseFileTask { pub(crate) handle: FileHandle, diff --git a/dnp3/src/master/tasks/file/directory.rs b/dnp3/src/master/tasks/file/directory.rs index 46104372..494e9270 100644 --- a/dnp3/src/master/tasks/file/directory.rs +++ b/dnp3/src/master/tasks/file/directory.rs @@ -1,5 +1,6 @@ use crate::app::{Group70Var7, MaybeAsync}; -use crate::master::{FileAction, FileError, FileInfo, FileReader, Promise}; +use crate::master::promise::Promise; +use crate::master::{FileAction, FileError, FileInfo, FileReader}; use scursor::ReadCursor; pub(crate) struct DirectoryReader { diff --git a/dnp3/src/master/tasks/file/get_info.rs b/dnp3/src/master/tasks/file/get_info.rs index 45654ba3..8c4692b9 100644 --- a/dnp3/src/master/tasks/file/get_info.rs +++ b/dnp3/src/master/tasks/file/get_info.rs @@ -4,8 +4,9 @@ use crate::app::format::WriteError; use crate::app::parse::free_format::FreeFormatVariation; use crate::app::parse::parser::{HeaderDetails, Response}; use crate::app::{FunctionCode, Timestamp}; +use crate::master::promise::Promise; use crate::master::tasks::{AppTask, NonReadTask, Task}; -use crate::master::{FileError, FileInfo, Promise, TaskError}; +use crate::master::{FileError, FileInfo, TaskError}; pub(crate) struct GetFileInfoTask { file_name: String, diff --git a/dnp3/src/master/tasks/file/open.rs b/dnp3/src/master/tasks/file/open.rs index f11a7f70..4d9d2d0c 100644 --- a/dnp3/src/master/tasks/file/open.rs +++ b/dnp3/src/master/tasks/file/open.rs @@ -3,9 +3,10 @@ use crate::app::format::WriteError; use crate::app::parse::free_format::FreeFormatVariation; use crate::app::parse::parser::{HeaderDetails, Response}; use crate::app::{FileStatus, FunctionCode, Group70Var3, Permissions, Timestamp}; +use crate::master::promise::Promise; use crate::master::tasks::file::REQUEST_ID; use crate::master::tasks::{AppTask, NonReadTask, Task}; -use crate::master::{AuthKey, FileError, FileHandle, FileMode, OpenFile, Promise, TaskError}; +use crate::master::{AuthKey, FileError, FileHandle, FileMode, OpenFile, TaskError}; pub(crate) struct OpenFileRequest { pub(crate) file_name: String, pub(crate) auth_key: AuthKey, diff --git a/dnp3/src/master/tasks/file/write_block.rs b/dnp3/src/master/tasks/file/write_block.rs index 77f34336..bd135046 100644 --- a/dnp3/src/master/tasks/file/write_block.rs +++ b/dnp3/src/master/tasks/file/write_block.rs @@ -3,8 +3,9 @@ use crate::app::format::WriteError; use crate::app::parse::free_format::FreeFormatVariation; use crate::app::parse::parser::{HeaderDetails, Response}; use crate::app::{FileStatus, FunctionCode, Group70Var5}; +use crate::master::promise::Promise; use crate::master::tasks::{AppTask, NonReadTask, Task}; -use crate::master::{BlockNumber, FileError, FileHandle, Promise, TaskError}; +use crate::master::{BlockNumber, FileError, FileHandle, TaskError}; pub(crate) struct WriteBlockRequest { pub(crate) handle: FileHandle, diff --git a/dnp3/src/master/tasks/mod.rs b/dnp3/src/master/tasks/mod.rs index 0b9ead7f..6e95593c 100644 --- a/dnp3/src/master/tasks/mod.rs +++ b/dnp3/src/master/tasks/mod.rs @@ -5,8 +5,8 @@ use crate::app::ResponseHeader; use crate::master::association::Association; use crate::master::error::TaskError; use crate::master::extract::extract_measurements; -use crate::master::handler::Promise; use crate::master::poll::Poll; +use crate::master::promise::Promise; use crate::master::request::{Classes, EventClasses}; use crate::master::tasks::auto::AutoTask; use crate::master::tasks::command::CommandTask; diff --git a/dnp3/src/master/tasks/read.rs b/dnp3/src/master/tasks/read.rs index 384c46b9..fb60ed9d 100644 --- a/dnp3/src/master/tasks/read.rs +++ b/dnp3/src/master/tasks/read.rs @@ -1,6 +1,6 @@ use crate::app::format::write::HeaderWriter; use crate::master::error::TaskError; -use crate::master::handler::Promise; +use crate::master::promise::Promise; use crate::master::request::ReadRequest; use crate::master::tasks::{AppTask, ReadTask, Task}; use crate::master::ReadHandler; diff --git a/dnp3/src/master/tasks/restart.rs b/dnp3/src/master/tasks/restart.rs index 65203236..1926f92d 100644 --- a/dnp3/src/master/tasks/restart.rs +++ b/dnp3/src/master/tasks/restart.rs @@ -4,7 +4,7 @@ use crate::app::gen::count::CountVariation; use crate::app::parse::parser::Response; use crate::app::FunctionCode; use crate::master::error::TaskError; -use crate::master::handler::Promise; +use crate::master::promise::Promise; use crate::master::tasks::{AppTask, NonReadTask, Task}; /// Type of restart to request diff --git a/dnp3/src/master/tasks/time.rs b/dnp3/src/master/tasks/time.rs index 98120bdf..f9f093b1 100644 --- a/dnp3/src/master/tasks/time.rs +++ b/dnp3/src/master/tasks/time.rs @@ -8,7 +8,7 @@ use crate::app::FunctionCode; use crate::app::Timestamp; use crate::master::association::Association; use crate::master::error::{TaskError, TimeSyncError}; -use crate::master::handler::Promise; +use crate::master::promise::Promise; use crate::master::request::TimeSyncProcedure; use crate::master::tasks::{AppTask, NonReadTask, Task}; diff --git a/dnp3/src/master/tests/harness/mod.rs b/dnp3/src/master/tests/harness/mod.rs index 6ed6c074..0f631402 100644 --- a/dnp3/src/master/tests/harness/mod.rs +++ b/dnp3/src/master/tests/harness/mod.rs @@ -8,8 +8,8 @@ use crate::link::header::{FrameInfo, FrameType}; use crate::link::reader::LinkModes; use crate::link::EndpointAddress; use crate::master::association::AssociationConfig; -use crate::master::handler::{AssociationHandle, MasterChannel, ReadHandler}; use crate::master::task::MasterTask; +use crate::master::{AssociationHandle, MasterChannel, ReadHandler}; use crate::master::{ AssociationHandler, AssociationInformation, HeaderInfo, MasterChannelConfig, MasterChannelType, }; @@ -22,7 +22,7 @@ struct DefaultAssociationHandler; impl AssociationHandler for DefaultAssociationHandler {} pub(crate) async fn create_association(mut config: AssociationConfig) -> TestHarness { - // use a 1 second timeout for all tests + // use a 1-second timeout for all tests config.response_timeout = Timeout::from_secs(1).unwrap(); let (io, io_handle) = sfio_tokio_mock_io::mock();