diff --git a/Cargo.lock b/Cargo.lock index 4623dca..8f2d7e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -25,9 +25,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -46,15 +46,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] @@ -78,9 +78,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "half" @@ -90,21 +90,21 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -112,9 +112,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "miniz_oxide" @@ -127,9 +127,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi", @@ -148,9 +148,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -167,9 +167,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", @@ -180,24 +180,24 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] @@ -244,9 +244,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.183" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", @@ -283,15 +283,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys", @@ -299,9 +299,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -310,9 +310,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.32.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "bytes", @@ -340,9 +340,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "wasi" @@ -361,9 +361,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1eeca1c172a285ee6c2c84c341ccea837e7c01b12fbb2d0fe3c9e550ce49ec8" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -376,42 +376,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b10d0c968ba7f6166195e13d593af609ec2e3d24f916f081690695cf5eaffb2f" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "571d8d4e62f26d4932099a9efe89660e8bd5087775a2ab5cdd8b747b811f1058" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2229ad223e178db5fbbc8bd8d3835e51e566b8474bfca58d2e6150c48bb723cd" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "600956e2d840c194eedfc5d18f8242bc2e17c7775b6684488af3a9fff6fe3287" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea99ff3f8b49fb7a8e0d305e5aec485bd068c2ba691b6e277d29eaeac945868a" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1a05a1ece9a7a0d5a7ccf30ba2c33e3a61a30e042ffd247567d1de1d94120d" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d419259aba16b663966e29e6d7c6ecfa0bb8425818bb96f6f1f3c3eb71a6e7b9" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/src/error.rs b/src/error.rs deleted file mode 100644 index 79b388a..0000000 --- a/src/error.rs +++ /dev/null @@ -1,239 +0,0 @@ -use crate::SeqNo; - -/// These are the error types that can be returned by a non-blocking SEQEX receive function. -/// -/// Some of these errors specify that SEQEX is waiting on some event to occur before it can proceed. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TryRawRecvError { - /// This packet had to be dropped because it arrived far enough out-of-order that it was outside - /// the receive window. - /// This packet will eventually be resent, so no data will be lost. - DroppedTooEarly, - /// This packet was a duplicate of a previously received packet. It must have been resent before - /// the remote peer received the ack for the packet. - /// Since this packet is a duplicate, no data is lost by dropping it. - DroppedDuplicate, - /// This packet was a duplicate of a previously received packet. We need to resend an Ack packet - /// containing the reply number within this error instance. - /// - /// So `Packet::Ack(SeqNo)` should be sent to the remote peer immediately. - DroppedDuplicateResendAck(SeqNo), - /// In order to preserve losslessness or in-order transport, the received packet cannot be - /// process until some other packet is received. The packet was saved to the receive window. - WaitingForRecv, - /// Either the receive window is full, or the received packet is SeqCst and cannot be processed - /// yet. In either case some currently issued reply number must be returned to SEQEX to send - /// either an Ack or a Reply. If using reply guards, then some currently existing reply guard - /// must be dropped or consumed. - /// Until this occurs the received packet cannot be processed. - /// - /// If the receive window was full, the packet was dropped. - /// Otherwise if the packet is SeqCst, then the packet was saved to the receive window. - WaitingForReply, -} - -/// These are the error types that can be returned by a blocking SEQEX receive function. -/// -/// Some of these errors specify that SEQEX is waiting on some event to occur before it can proceed. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TryRecvError { - /// This packet had to be dropped because it arrived far enough out-of-order that it was outside - /// the receive window. - /// This packet will eventually be resent, so no data will be lost. - DroppedTooEarly, - /// This packet was a duplicate of a previously received packet. It must have been resent before - /// the remote peer received the ack for the packet. - /// Since this packet is a duplicate, no data is lost by dropping it. - DroppedDuplicate, - /// In order to preserve losslessness or in-order transport, the received packet cannot be - /// process until some other packet is received. The packet was saved to the receive window. - WaitingForRecv, - /// Either the receive window is full, or the received packet is SeqCst and cannot enter the - /// critical section where it is processed. In either case there currently exists some reply - /// guard that must be dropped or consumed before this packet can be processed. - /// - /// If the receive window was full, the packet was dropped. - /// Otherwise if the packet is SeqCst, then the packet was saved to the receive window. - WaitingForReply, -} - -/// These are the error types that can be returned by a blocking SEQEX receive function. -/// -/// Some of these errors specify that SEQEX is waiting on some event to occur before it can proceed. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum RecvError { - /// This packet had to be dropped because it arrived far enough out-of-order that it was outside - /// the receive window. - /// This packet will eventually be resent, so no data will be lost. - DroppedTooEarly, - /// This packet was a duplicate of a previously received packet. It must have been resent before - /// the remote peer received the ack for the packet. - /// Since this packet is a duplicate, no data is lost by dropping it. - DroppedDuplicate, - /// In order to preserve losslessness or in-order transport, the received packet cannot be - /// process until some other packet is received. The packet was saved to the receive window. - WaitingForRecv, - /// Either the receive window is full, or the received packet is SeqCst and cannot enter the - /// critical section where it is processed. In either case there currently exists some reply - /// guard that must be dropped or consumed before this packet can be processed. - /// - /// If the receive window was full, the packet was dropped. - /// Otherwise if the packet is SeqCst, then the packet was saved to the receive window. - WaitingForReply, - /// This instance of `SeqEx` has been explicitly closed. - /// It can no longer send or receive data. - /// - /// This error can only occur after `SeqEx::close` has been called. - /// An instance of `SeqEx` will never close by itself, only the caller can close it. - Closed, -} - -/// A generic error that can be returned by a `try_send` or `try_pump` function. -/// They specify what event must occur before a future call to `try_send` or `try_pump` can succeed. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TryError { - /// The packet could not be sent or processed at this time. - /// Some other packet must be received from the remote peer first. - WaitingForRecv, - /// Some currently issued reply number must be returned to SEQEX to send either an Ack or a - /// Reply. If using reply guards, then some currently existing reply guard must be dropped or - /// consumed. - /// Until this occurs the packet cannot be sent or processed. - WaitingForReply, -} -/// A generic error that can be returned by a `try_send` or `try_pump` function. -/// They specify what event must occur before a future call to `try_send` or `try_pump` can succeed. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TrySendError { - /// The packet could not be sent or processed at this time. - /// Some other packet must be received from the remote peer first. - WaitingForRecv, - /// Some currently issued reply number must be returned to SEQEX to send either an Ack or a - /// Reply. If using reply guards, then some currently existing reply guard must be dropped or - /// consumed. - /// Until this occurs the packet cannot be sent or processed. - WaitingForReply, - /// This instance of `SeqEx` has been explicitly closed. - /// It can no longer send or receive data. - /// - /// This error can only occur after `SeqEx::close` has been called. - /// An instance of `SeqEx` will never close by itself, only the caller can close it. - Closed, -} -/// This instance of `SeqEx` has been explicitly closed. -/// It can no longer send or receive data. -/// -/// This error can only occur after `SeqEx::close` has been called. -/// An instance of `SeqEx` will never close by itself, only the caller can close it. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ClosedError; - -#[cfg(feature = "std")] -impl std::fmt::Display for TryRawRecvError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TryRawRecvError::DroppedTooEarly => write!(f, "packet arrived too early"), - TryRawRecvError::DroppedDuplicate => write!(f, "packet was a duplicate"), - TryRawRecvError::DroppedDuplicateResendAck(_) => write!(f, "packet was a duplicate, resending ack"), - TryRawRecvError::WaitingForRecv => write!(f, "can't process until another packet is received"), - TryRawRecvError::WaitingForReply => write!(f, "can't process until a reply is finished"), - } - } -} -#[cfg(feature = "std")] -impl std::error::Error for TryRawRecvError {} - -#[cfg(feature = "std")] -impl std::fmt::Display for TryRecvError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::DroppedTooEarly => write!(f, "packet arrived too early"), - Self::DroppedDuplicate => write!(f, "packet was a duplicate"), - Self::WaitingForRecv => write!(f, "can't process packet until another packet is received"), - Self::WaitingForReply => write!(f, "can't process packet until a reply is finished"), - } - } -} -#[cfg(feature = "std")] -impl std::error::Error for TryRecvError {} - -#[cfg(feature = "std")] -impl std::fmt::Display for RecvError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::DroppedTooEarly => write!(f, "packet arrived too early"), - Self::DroppedDuplicate => write!(f, "packet was a duplicate"), - Self::WaitingForRecv => write!(f, "can't process packet until another packet is received"), - Self::WaitingForReply => write!(f, "can't process packet until a reply is finished"), - Self::Closed => write!(f, "can't receive packet because the session was explicitly closed"), - } - } -} -#[cfg(feature = "std")] -impl std::error::Error for RecvError {} - -#[cfg(feature = "std")] -impl std::fmt::Display for TryError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TryError::WaitingForRecv => write!(f, "can't process until another packet is received"), - TryError::WaitingForReply => write!(f, "can't process until a reply is finished"), - } - } -} -#[cfg(feature = "std")] -impl std::error::Error for TryError {} - -#[cfg(feature = "std")] -impl std::fmt::Display for TrySendError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TrySendError::WaitingForRecv => write!(f, "can't send until another packet is received"), - TrySendError::WaitingForReply => write!(f, "can't send until a reply is finished"), - TrySendError::Closed => write!(f, "can't send because the session was explicitly closed"), - } - } -} -#[cfg(feature = "std")] -impl std::error::Error for TrySendError {} - -#[cfg(feature = "std")] -impl std::fmt::Display for ClosedError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "can't send because the session was explicitly closed") - } -} -#[cfg(feature = "std")] -impl std::error::Error for ClosedError {} - -impl From for RecvError { - fn from(value: TryRecvError) -> Self { - match value { - TryRecvError::DroppedTooEarly => RecvError::DroppedTooEarly, - TryRecvError::DroppedDuplicate => RecvError::DroppedDuplicate, - TryRecvError::WaitingForRecv => RecvError::WaitingForRecv, - TryRecvError::WaitingForReply => RecvError::WaitingForReply, - } - } -} - -impl From for TrySendError { - fn from(value: TryError) -> Self { - match value { - TryError::WaitingForRecv => TrySendError::WaitingForRecv, - TryError::WaitingForReply => TrySendError::WaitingForReply, - } - } -} - -impl From for TryRecvError { - fn from(value: TryRawRecvError) -> Self { - match value { - TryRawRecvError::DroppedTooEarly => TryRecvError::DroppedTooEarly, - TryRawRecvError::DroppedDuplicate => TryRecvError::DroppedDuplicate, - TryRawRecvError::DroppedDuplicateResendAck(_) => TryRecvError::DroppedDuplicate, - TryRawRecvError::WaitingForRecv => TryRecvError::WaitingForRecv, - TryRawRecvError::WaitingForReply => TryRecvError::WaitingForReply, - } - } -} diff --git a/src/lib.rs b/src/lib.rs index f93c580..209b903 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,9 +38,6 @@ mod transport_layer; pub use transport_layer::*; -/// Module which contains the various error types that can be returned by SEQEX. -pub mod error; - /// This module contains the API for using SEQEX in a no-std environment. /// This API is low level and is the backbone of the `sync` and `tokio` implementations of SEQEX. /// diff --git a/src/no_std.rs b/src/no_std.rs index f947a4b..d9d643b 100644 --- a/src/no_std.rs +++ b/src/no_std.rs @@ -1,12 +1,8 @@ -pub use crate::single_thread::*; - -use crate::{ - error::{TryError, TryRawRecvError}, - transport_layer::SeqNo, - Packet, DEFAULT_INITIAL_SEQ_NO, DEFAULT_RESEND_INTERVAL_MS, DEFAULT_WINDOW_CAP, -}; +use crate::{transport_layer::SeqNo, Packet, DEFAULT_INITIAL_SEQ_NO, DEFAULT_RESEND_INTERVAL_MS, DEFAULT_WINDOW_CAP}; use Packet::*; +pub use crate::single_thread::*; + #[derive(Debug)] pub struct SeqEx { /// The interval at which packets will be resent if they have not yet been acknowledged by the diff --git a/src/single_thread.rs b/src/single_thread.rs index ea9a752..cce7621 100644 --- a/src/single_thread.rs +++ b/src/single_thread.rs @@ -1,4 +1,3 @@ -use crate::error::{TryError, TryRawRecvError, TryRecvError}; use crate::no_std::{RecvOkRaw, SeqEx}; use crate::{Packet, SeqNo, TransportLayer, DEFAULT_WINDOW_CAP}; @@ -293,3 +292,126 @@ impl SeqEx { self.try_pump_raw().map(|(r, do_pump)| (RecvOk::from_raw(self, tl, r), do_pump)) } } + +/// These are the error types that can be returned by a non-blocking SEQEX receive function. +/// +/// Some of these errors specify that SEQEX is waiting on some event to occur before it can proceed. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum TryRawRecvError { + /// This packet had to be dropped because it arrived far enough out-of-order that it was outside + /// the receive window. + /// This packet will eventually be resent, so no data will be lost. + DroppedTooEarly, + /// This packet was a duplicate of a previously received packet. It must have been resent before + /// the remote peer received the ack for the packet. + /// Since this packet is a duplicate, no data is lost by dropping it. + DroppedDuplicate, + /// This packet was a duplicate of a previously received packet. We need to resend an Ack packet + /// containing the reply number within this error instance. + /// + /// So `Packet::Ack(SeqNo)` should be sent to the remote peer immediately. + DroppedDuplicateResendAck(SeqNo), + /// In order to preserve losslessness or in-order transport, the received packet cannot be + /// process until some other packet is received. The packet was saved to the receive window. + WaitingForRecv, + /// Either the receive window is full, or the received packet is SeqCst and cannot be processed + /// yet. In either case some currently issued reply number must be returned to SEQEX to send + /// either an Ack or a Reply. If using reply guards, then some currently existing reply guard + /// must be dropped or consumed. + /// Until this occurs the received packet cannot be processed. + /// + /// If the receive window was full, the packet was dropped. + /// Otherwise if the packet is SeqCst, then the packet was saved to the receive window. + WaitingForReply, +} + +/// These are the error types that can be returned by a blocking SEQEX receive function. +/// +/// Some of these errors specify that SEQEX is waiting on some event to occur before it can proceed. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum TryRecvError { + /// This packet had to be dropped because it arrived far enough out-of-order that it was outside + /// the receive window. + /// This packet will eventually be resent, so no data will be lost. + DroppedTooEarly, + /// This packet was a duplicate of a previously received packet. It must have been resent before + /// the remote peer received the ack for the packet. + /// Since this packet is a duplicate, no data is lost by dropping it. + DroppedDuplicate, + /// In order to preserve losslessness or in-order transport, the received packet cannot be + /// process until some other packet is received. The packet was saved to the receive window. + WaitingForRecv, + /// Either the receive window is full, or the received packet is SeqCst and cannot enter the + /// critical section where it is processed. In either case there currently exists some reply + /// guard that must be dropped or consumed before this packet can be processed. + /// + /// If the receive window was full, the packet was dropped. + /// Otherwise if the packet is SeqCst, then the packet was saved to the receive window. + WaitingForReply, +} + +/// A generic error that can be returned by a `try_send` or `try_pump` function. +/// They specify what event must occur before a future call to `try_send` or `try_pump` can succeed. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum TryError { + /// The packet could not be sent or processed at this time. + /// Some other packet must be received from the remote peer first. + WaitingForRecv, + /// Some currently issued reply number must be returned to SEQEX to send either an Ack or a + /// Reply. If using reply guards, then some currently existing reply guard must be dropped or + /// consumed. + /// Until this occurs the packet cannot be sent or processed. + WaitingForReply, +} +#[cfg(feature = "std")] +impl std::fmt::Display for TryRawRecvError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TryRawRecvError::DroppedTooEarly => write!(f, "packet arrived too early"), + TryRawRecvError::DroppedDuplicate => write!(f, "packet was a duplicate"), + TryRawRecvError::DroppedDuplicateResendAck(_) => write!(f, "packet was a duplicate, resending ack"), + TryRawRecvError::WaitingForRecv => write!(f, "can't process until another packet is received"), + TryRawRecvError::WaitingForReply => write!(f, "can't process until a reply is finished"), + } + } +} +#[cfg(feature = "std")] +impl std::error::Error for TryRawRecvError {} + +#[cfg(feature = "std")] +impl std::fmt::Display for TryRecvError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::DroppedTooEarly => write!(f, "packet arrived too early"), + Self::DroppedDuplicate => write!(f, "packet was a duplicate"), + Self::WaitingForRecv => write!(f, "can't process packet until another packet is received"), + Self::WaitingForReply => write!(f, "can't process packet until a reply is finished"), + } + } +} +#[cfg(feature = "std")] +impl std::error::Error for TryRecvError {} + +#[cfg(feature = "std")] +impl std::fmt::Display for TryError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TryError::WaitingForRecv => write!(f, "can't process until another packet is received"), + TryError::WaitingForReply => write!(f, "can't process until a reply is finished"), + } + } +} +#[cfg(feature = "std")] +impl std::error::Error for TryError {} + +impl From for TryRecvError { + fn from(value: TryRawRecvError) -> Self { + match value { + TryRawRecvError::DroppedTooEarly => TryRecvError::DroppedTooEarly, + TryRawRecvError::DroppedDuplicate => TryRecvError::DroppedDuplicate, + TryRawRecvError::DroppedDuplicateResendAck(_) => TryRecvError::DroppedDuplicate, + TryRawRecvError::WaitingForRecv => TryRecvError::WaitingForRecv, + TryRawRecvError::WaitingForReply => TryRecvError::WaitingForReply, + } + } +} diff --git a/src/sync.rs b/src/sync.rs index d7fa42b..b6ab4e2 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -6,11 +6,9 @@ use std::{ time::Instant, }; -use crate::{ - error::{ClosedError, RecvError, TryError, TrySendError}, - no_std::RecvOkRaw, - Packet, SeqNo, TransportLayer, DEFAULT_INITIAL_SEQ_NO, DEFAULT_RESEND_INTERVAL_MS, DEFAULT_WINDOW_CAP, -}; +use crate::{no_std::RecvOkRaw, Packet, SeqNo, TransportLayer, DEFAULT_INITIAL_SEQ_NO, DEFAULT_RESEND_INTERVAL_MS, DEFAULT_WINDOW_CAP}; + +pub use crate::no_std::TryError; /// The core thread-safe datastructure which manages the SEQEX protocol. /// @@ -385,17 +383,22 @@ impl SeqEx { &self, tl: TL, packet: Packet, - ) -> Result<(RecvOk<'_, TL, SendData, RecvData, CAP>, bool), RecvError> { + ) -> Result<(RecvOk<'_, TL, SendData, RecvData, CAP>, bool), TryRecvError> { let mut inner = self.inner.lock().unwrap(); if inner.closed { - return Err(RecvError::Closed); + return Err(TryRecvError::Closed); } match inner.seq.try_receive_raw(tl, packet) { Ok((r, do_pump)) => { self.notify_recv(inner); Ok((RecvOk::from_raw(self, tl, r), do_pump)) } - Err(e) => Err(e.into()), + Err(e) => Err(match e { + crate::no_std::TryRecvError::DroppedTooEarly => TryRecvError::DroppedTooEarly, + crate::no_std::TryRecvError::DroppedDuplicate => TryRecvError::DroppedDuplicate, + crate::no_std::TryRecvError::WaitingForRecv => TryRecvError::WaitingForRecv, + crate::no_std::TryRecvError::WaitingForReply => TryRecvError::WaitingForReply, + }), } } /// A SEQEX packet was just received and deserialized from the transport layer. @@ -418,12 +421,21 @@ impl SeqEx { tl: TL, packet: Packet, ) -> Result<(RecvOk<'_, TL, SendData, RecvData, CAP>, bool), RecvError> { - let result = self.try_receive(tl, packet); - if let Err(RecvError::WaitingForReply) = result { - self.pump(tl).ok_or(RecvError::WaitingForReply) - } else { - result + match self.try_receive(tl, packet) { + Ok(r) => Ok(r), + Err(e) => match e { + TryRecvError::WaitingForReply => self.pump(tl).ok_or(RecvError::WaitingForRecv), + TryRecvError::WaitingForRecv => Err(RecvError::WaitingForRecv), + TryRecvError::DroppedTooEarly => Err(RecvError::DroppedTooEarly), + TryRecvError::DroppedDuplicate => Err(RecvError::DroppedDuplicate), + TryRecvError::Closed => Err(RecvError::Closed), + }, } + //if let Err(TryRecvError::WaitingForReply) = result { + // self.pump(tl).ok_or(RecvError::WaitingForRecv) + //} else { + // result + //} } /// Non-blocking variant of `SeqEx::pump`. /// See the documentation for `SeqEx::pump` for more information. @@ -790,3 +802,145 @@ impl TransportLayer for &MpscTransport { let _ = self.channel.send(packet.cloned()); } } + +/// These are the error types that can be returned by `SeqEx::try_receive`. +/// +/// Some of these errors specify that SEQEX is waiting on some event to occur before it can proceed. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum TryRecvError { + /// Either the receive window is full, or the received packet is SeqCst and cannot enter the + /// critical section where it is processed. In either case there currently exists some reply + /// guard that must be dropped or consumed before this packet can be processed. + /// + /// If the receive window was full, the packet was dropped. + /// Otherwise if the packet is SeqCst, then the packet was saved to the receive window. + WaitingForReply, + /// In order to preserve losslessness or in-order transport, the received packet cannot be + /// process until some other packet is received. The packet was saved to the receive window. + WaitingForRecv, + /// This packet had to be dropped because it arrived far enough out-of-order that it was outside + /// the receive window. + /// This packet will eventually be resent, so no data will be lost. + DroppedTooEarly, + /// This packet was a duplicate of a previously received packet. It must have been resent before + /// the remote peer received the ack for the packet. + /// Since this packet is a duplicate, no data is lost by dropping it. + DroppedDuplicate, + /// This instance of `SeqEx` has been explicitly closed. + /// It can no longer send or receive data. + /// + /// This error can only occur after `SeqEx::close` has been called. + /// An instance of `SeqEx` will never close by itself, only the caller can close it. + Closed, +} +/// These are the error types that can be returned by `SeqEx::receive`. +/// +/// Some of these errors specify that SEQEX is waiting on some event to occur before it can proceed. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum RecvError { + /// In order to preserve losslessness or in-order transport, the received packet cannot be + /// process until some other packet is received. The packet was saved to the receive window. + WaitingForRecv, + /// This packet had to be dropped because it arrived far enough out-of-order that it was outside + /// the receive window. + /// This packet will eventually be resent, so no data will be lost. + DroppedTooEarly, + /// This packet was a duplicate of a previously received packet. It must have been resent before + /// the remote peer received the ack for the packet. + /// Since this packet is a duplicate, no data is lost by dropping it. + DroppedDuplicate, + /// This instance of `SeqEx` has been explicitly closed. + /// It can no longer send or receive data. + /// + /// This error can only occur after `SeqEx::close` has been called. + /// An instance of `SeqEx` will never close by itself, only the caller can close it. + Closed, +} +/// A generic error that can be returned by a `try_send` or `try_pump` function. +/// They specify what event must occur before a future call to `try_send` or `try_pump` can succeed. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum TrySendError { + /// The packet could not be sent or processed at this time. + /// Some other packet must be received from the remote peer first. + WaitingForRecv, + /// Some currently issued reply number must be returned to SEQEX to send either an Ack or a + /// Reply. If using reply guards, then some currently existing reply guard must be dropped or + /// consumed. + /// Until this occurs the packet cannot be sent or processed. + WaitingForReply, + /// This instance of `SeqEx` has been explicitly closed. + /// It can no longer send or receive data. + /// + /// This error can only occur after `SeqEx::close` has been called. + /// An instance of `SeqEx` will never close by itself, only the caller can close it. + Closed, +} + +/// This instance of `SeqEx` has been explicitly closed. +/// It can no longer send or receive data. +/// +/// This error can only occur after `SeqEx::close` has been called. +/// An instance of `SeqEx` will never close by itself, only the caller can close it. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct ClosedError; + +impl std::fmt::Display for TryRecvError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::DroppedTooEarly => write!(f, "packet arrived too early"), + Self::DroppedDuplicate => write!(f, "packet was a duplicate"), + Self::WaitingForRecv => write!(f, "can't process packet until another packet is received"), + Self::WaitingForReply => write!(f, "can't process packet until a reply is finished"), + Self::Closed => write!(f, "can't receive packet because the session was explicitly closed"), + } + } +} +impl std::error::Error for TryRecvError {} + +impl std::fmt::Display for RecvError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let e: TryRecvError = (*self).into(); + e.fmt(f) + } +} +impl std::error::Error for RecvError {} + +#[cfg(feature = "std")] +impl std::fmt::Display for TrySendError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TrySendError::WaitingForRecv => write!(f, "can't send until another packet is received"), + TrySendError::WaitingForReply => write!(f, "can't send until a reply is finished"), + TrySendError::Closed => write!(f, "can't send because the session was explicitly closed"), + } + } +} +#[cfg(feature = "std")] +impl std::error::Error for TrySendError {} + +impl std::fmt::Display for ClosedError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "can't send because the session was explicitly closed") + } +} +impl std::error::Error for ClosedError {} + +impl From for TryRecvError { + fn from(value: RecvError) -> Self { + match value { + RecvError::WaitingForRecv => TryRecvError::WaitingForRecv, + RecvError::DroppedTooEarly => TryRecvError::DroppedTooEarly, + RecvError::DroppedDuplicate => TryRecvError::DroppedDuplicate, + RecvError::Closed => TryRecvError::Closed, + } + } +} + +impl From for TrySendError { + fn from(value: TryError) -> Self { + match value { + TryError::WaitingForRecv => TrySendError::WaitingForRecv, + TryError::WaitingForReply => TrySendError::WaitingForReply, + } + } +}