diff --git a/Cargo.lock b/Cargo.lock index ac50b7b98e6..e6f666c1b52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2625,12 +2625,11 @@ dependencies = [ "error-stack", "futures-core", "futures-util", + "harpc-types", "memchr", "pin-project-lite", - "proptest", "serde", "serde_json", - "test-strategy", "tokio", ] @@ -2691,7 +2690,6 @@ dependencies = [ "harpc-service", "harpc-tower", "harpc-types", - "harpc-wire-protocol", "scc", "serde", "thiserror", @@ -2708,7 +2706,6 @@ dependencies = [ "frunk", "harpc-tower", "harpc-types", - "harpc-wire-protocol", ] [[package]] @@ -2723,7 +2720,6 @@ dependencies = [ "harpc-codec", "harpc-net", "harpc-types", - "harpc-wire-protocol", "insta", "pin-project", "pin-project-lite", diff --git a/libs/@local/harpc/codec/Cargo.toml b/libs/@local/harpc/codec/Cargo.toml index 5e5b346d32c..6934750daa2 100644 --- a/libs/@local/harpc/codec/Cargo.toml +++ b/libs/@local/harpc/codec/Cargo.toml @@ -11,6 +11,7 @@ publish.workspace = true [dependencies] # Public workspace dependencies error-stack = { workspace = true, public = true, features = ["serde"] } +harpc-types = { workspace = true, public = true } # Public third-party dependencies bytes = { workspace = true, public = true } @@ -18,15 +19,13 @@ futures-core = { workspace = true, public = true } serde = { workspace = true, public = true, features = ["derive"]} # Private workspace dependencies -proptest = { workspace = true, optional = true } -test-strategy = { workspace = true, optional = true } + +# Private third-party dependencies futures-util = { workspace = true, optional = true } serde_json = { workspace = true, optional = true, public = true } pin-project-lite = { workspace = true, optional = true } memchr = { workspace = true, optional = true } -# Private third-party dependencies - [dev-dependencies] tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } @@ -34,5 +33,4 @@ tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } workspace = true [features] -proptest = ["dep:proptest", "dep:test-strategy"] json = ["dep:serde_json", "dep:pin-project-lite", "dep:futures-util", "dep:memchr"] diff --git a/libs/@local/harpc/codec/src/error.rs b/libs/@local/harpc/codec/src/error.rs index 69435acbaf0..61f4f869094 100644 --- a/libs/@local/harpc/codec/src/error.rs +++ b/libs/@local/harpc/codec/src/error.rs @@ -1,137 +1,10 @@ -use core::{marker::PhantomData, num::NonZero}; +use core::marker::PhantomData; use bytes::{Buf, BufMut, Bytes, BytesMut}; +use harpc_types::error_code::ErrorCode; use self::kind::ErrorKind; -macro_rules! non_zero { - ($n:expr) => {{ - // ensure that the value is not 0, in case it is, panic during compile time - const { - assert!($n != 0, "value must not be 0"); - } - - #[expect(unsafe_code, reason = "checked that it is never 0")] - // SAFETY: $value is not 0 - unsafe { - NonZero::new_unchecked($n) - } - }}; -} - -// we use a macro here to define the error codes, as the code is quite repetetive and also error -// prone, we might not be able to increment values correctly, another problem is that rustfmt will -// reorder the constants, making keeping tracks of the ids harder than it should be. -macro_rules! define_error_code_consts { - ($( - $(#[$meta:meta])* - $base:literal => [$( - $(#[$name_meta:meta])* - $name:ident - ),+] - ),*) => { - $( - $(#[$meta])* - impl ErrorCode { - $( - $(#[$name_meta])* - /// - /// - /// **Error Code**: ` - #[doc = stringify!($base)] - #[doc = "+"] - #[doc = stringify!(${index(0)})] - #[doc = "`"] - pub const $name: Self = Self(non_zero!($base + ${index(0)})); - )+ - } - )* - }; -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize)] -#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))] -pub struct ErrorCode(NonZero); - -impl ErrorCode { - #[must_use] - pub const fn new(value: NonZero) -> Self { - Self(value) - } - - #[must_use] - pub const fn value(self) -> NonZero { - self.0 - } -} - -impl<'de> serde::Deserialize<'de> for ErrorCode { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let value = u16::deserialize(deserializer)?; - - NonZero::new(value) - .map(Self) - .ok_or_else(|| serde::de::Error::custom("value must not be 0")) - } -} - -define_error_code_consts! { - // 0xFE_xx = client errors - /// Errors initiated by the client, but that occur on the server. - /// - /// These errors are issued on the higher-level tower implementation. - 0xFE_10 => [ - /// The combination of service and version requirement could not be found on the server. - /// - /// The HTTP equivalent is 404 Not Found. - NOT_FOUND - ], - // 0xFF_xx = server errors - /// Errors that occur in a session and are issued by the server. - /// - /// These errors are issued on the lower-level network layer. - 0xFF_00 => [ - /// Server is shutting down. - /// - /// The server is in the process of shutting down and no longer acceptts new connections. - CONNECTION_SHUTDOWN, - /// Connection transaction limit reached. - /// - /// The total count of concurrent transaction per connection has been reached. - CONNECTION_TRANSACTION_LIMIT_REACHED, - /// Instance transaction limit reached. - /// - /// The total count of concurrent transaction per server node has been reached. - INSTANCE_TRANSACTION_LIMIT_REACHED, - /// Transaction is lagging behind. - /// - /// The client sent too many packets that haven't been processed by the server yet, - /// which lead to packets dropping and the transaction being cancelled. - TRANSACTION_LAGGING - ], - /// Errors that occur due to malformed payloads in the tower layer. - 0xFF_10 => [ - /// Encoded error encountered an invalid error tag. - /// - /// The returned payload for an encoded error does not have a valid error tag to distinguish - /// between the different error encodings and could therefore not be properly encoded. - /// - /// This is a fault in the implementation of the server, either in the `codec` or - /// the `tower` layer. - PACK_INVALID_ERROR_TAG - ], - /// Generic server errors. - 0xFF_F0 => [ - /// An internal server error occurred. - /// - /// An unknown error occurred on the server. - INTERNAL_SERVER_ERROR - ] -} - /// An error that is has been fully encoded and can be sent or received over the network. /// /// Essentially a compiled version of a `NetworkError` or `Report` into it's wire format. diff --git a/libs/@local/harpc/codec/src/json.rs b/libs/@local/harpc/codec/src/json.rs index cf5407bfc06..d386346db99 100644 --- a/libs/@local/harpc/codec/src/json.rs +++ b/libs/@local/harpc/codec/src/json.rs @@ -8,12 +8,13 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; use error_stack::Report; use futures_core::Stream; use futures_util::stream::StreamExt; +use harpc_types::error_code::ErrorCode; use serde::{de::DeserializeOwned, ser::Error as _}; use crate::{ decode::{Decoder, ErrorDecoder}, encode::{Encoder, ErrorEncoder}, - error::{EncodedError, ErrorBuffer, ErrorCode, NetworkError}, + error::{EncodedError, ErrorBuffer, NetworkError}, }; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] diff --git a/libs/@local/harpc/net/Cargo.toml b/libs/@local/harpc/net/Cargo.toml index 4a1e613df75..da6301ab517 100644 --- a/libs/@local/harpc/net/Cargo.toml +++ b/libs/@local/harpc/net/Cargo.toml @@ -10,6 +10,8 @@ authors.workspace = true [dependencies] # Public workspace dependencies +harpc-codec = { workspace = true, public = true } + # Public third-party dependencies futures-core = { workspace = true, public = true } @@ -30,7 +32,7 @@ tokio = { workspace = true, public = true, features = ["io-util", "macros"] } codec = { workspace = true, features = ["harpc"] } error-stack = { workspace = true } harpc-wire-protocol = { workspace = true } -harpc-codec = { workspace = true } +harpc-types = { workspace = true } # Private third-party dependencies bytes = { workspace = true } diff --git a/libs/@local/harpc/net/src/session/client/connection/mod.rs b/libs/@local/harpc/net/src/session/client/connection/mod.rs index 806a49a1818..2bed54a0cc8 100644 --- a/libs/@local/harpc/net/src/session/client/connection/mod.rs +++ b/libs/@local/harpc/net/src/session/client/connection/mod.rs @@ -8,10 +8,8 @@ use alloc::sync::Arc; use bytes::Bytes; use error_stack::Report; use futures::{Sink, Stream, StreamExt, prelude::future::FutureExt}; -use harpc_wire_protocol::{ - request::{Request, procedure::ProcedureDescriptor, service::ServiceDescriptor}, - response::Response, -}; +use harpc_types::{procedure::ProcedureDescriptor, service::ServiceDescriptor}; +use harpc_wire_protocol::{request::Request, response::Response}; use scc::ebr::Guard; use tachyonix::SendTimeoutError; use tokio::{ diff --git a/libs/@local/harpc/net/src/session/client/connection/test.rs b/libs/@local/harpc/net/src/session/client/connection/test.rs index 58f38dde172..c74c519cc5a 100644 --- a/libs/@local/harpc/net/src/session/client/connection/test.rs +++ b/libs/@local/harpc/net/src/session/client/connection/test.rs @@ -9,6 +9,7 @@ use std::io; use bytes::{Buf, BufMut, Bytes, BytesMut}; use error_stack::Report; use futures::{StreamExt, stream}; +use harpc_types::response_kind::ResponseKind; use harpc_wire_protocol::{ flags::BitFlagsOp, payload::Payload, @@ -28,7 +29,6 @@ use harpc_wire_protocol::{ flags::{ResponseFlag, ResponseFlags}, frame::ResponseFrame, header::ResponseHeader, - kind::ResponseKind, }, test_utils::mock_request_id, }; diff --git a/libs/@local/harpc/net/src/session/client/transaction/mod.rs b/libs/@local/harpc/net/src/session/client/transaction/mod.rs index b66f30b24cd..6fa1ab64109 100644 --- a/libs/@local/harpc/net/src/session/client/transaction/mod.rs +++ b/libs/@local/harpc/net/src/session/client/transaction/mod.rs @@ -7,12 +7,15 @@ use core::ops::ControlFlow; use bytes::Bytes; use futures::{Stream, StreamExt, prelude::future::FutureExt}; +use harpc_types::{ + procedure::ProcedureDescriptor, response_kind::ResponseKind, service::ServiceDescriptor, +}; use harpc_wire_protocol::{ flags::BitFlagsOp, - request::{Request, id::RequestId, procedure::ProcedureDescriptor, service::ServiceDescriptor}, + request::{Request, id::RequestId}, response::{ Response, begin::ResponseBegin, body::ResponseBody, flags::ResponseFlag, - frame::ResponseFrame, kind::ResponseKind, + frame::ResponseFrame, }, }; use tokio::{pin, select, sync::mpsc}; diff --git a/libs/@local/harpc/net/src/session/client/transaction/stream.rs b/libs/@local/harpc/net/src/session/client/transaction/stream.rs index f7ae69d84c1..46b4cfabecc 100644 --- a/libs/@local/harpc/net/src/session/client/transaction/stream.rs +++ b/libs/@local/harpc/net/src/session/client/transaction/stream.rs @@ -3,7 +3,7 @@ use core::sync::atomic::{AtomicU8, Ordering}; use bytes::Bytes; use futures::{Stream, StreamExt, stream::FusedStream}; -use harpc_codec::error::ErrorCode; +use harpc_types::error_code::ErrorCode; use crate::stream::TerminatedChannelStream; diff --git a/libs/@local/harpc/net/src/session/client/transaction/test.rs b/libs/@local/harpc/net/src/session/client/transaction/test.rs index c4152957405..dd2ab7cf489 100644 --- a/libs/@local/harpc/net/src/session/client/transaction/test.rs +++ b/libs/@local/harpc/net/src/session/client/transaction/test.rs @@ -3,7 +3,7 @@ use core::{assert_matches::assert_matches, num::NonZero, time::Duration}; use bytes::{Bytes, BytesMut}; use futures::StreamExt; -use harpc_codec::error::ErrorCode; +use harpc_types::{error_code::ErrorCode, response_kind::ResponseKind}; use harpc_wire_protocol::{ flags::BitFlagsOp, payload::Payload, @@ -19,7 +19,6 @@ use harpc_wire_protocol::{ flags::{ResponseFlag, ResponseFlags}, frame::ResponseFrame, header::ResponseHeader, - kind::ResponseKind, }, test_utils::mock_request_id, }; diff --git a/libs/@local/harpc/net/src/session/error.rs b/libs/@local/harpc/net/src/session/error.rs index c14671728a7..ea38bbd96e0 100644 --- a/libs/@local/harpc/net/src/session/error.rs +++ b/libs/@local/harpc/net/src/session/error.rs @@ -1,6 +1,6 @@ use core::error::{Error, Request}; -use harpc_codec::error::ErrorCode; +use harpc_types::error_code::ErrorCode; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, thiserror::Error)] #[error("The session layer has encountered an error, the connection has been closed")] diff --git a/libs/@local/harpc/net/src/session/server/connection/mod.rs b/libs/@local/harpc/net/src/session/server/connection/mod.rs index 3794cd958a4..2968e04f412 100644 --- a/libs/@local/harpc/net/src/session/server/connection/mod.rs +++ b/libs/@local/harpc/net/src/session/server/connection/mod.rs @@ -8,9 +8,10 @@ use std::io; use futures::{FutureExt, Sink, Stream, StreamExt, stream}; use harpc_codec::encode::ErrorEncoder; +use harpc_types::response_kind::ResponseKind; use harpc_wire_protocol::{ request::{Request, body::RequestBody, id::RequestId}, - response::{Response, kind::ResponseKind}, + response::Response, }; use libp2p::PeerId; use tokio::{ diff --git a/libs/@local/harpc/net/src/session/server/connection/test.rs b/libs/@local/harpc/net/src/session/server/connection/test.rs index 9a29076133e..73888aeaefa 100644 --- a/libs/@local/harpc/net/src/session/server/connection/test.rs +++ b/libs/@local/harpc/net/src/session/server/connection/test.rs @@ -5,7 +5,8 @@ use std::io; use bytes::{Buf, Bytes}; use futures::{StreamExt, prelude::sink::SinkExt}; -use harpc_codec::{error::ErrorCode, json::JsonCodec}; +use harpc_codec::json::JsonCodec; +use harpc_types::{error_code::ErrorCode, response_kind::ResponseKind}; use harpc_wire_protocol::{ flags::BitFlagsOp, payload::Payload, @@ -22,7 +23,6 @@ use harpc_wire_protocol::{ flags::{ResponseFlag, ResponseFlags}, frame::ResponseFrame, header::ResponseHeader, - kind::ResponseKind, }, test_utils::mock_request_id, }; diff --git a/libs/@local/harpc/net/src/session/server/test.rs b/libs/@local/harpc/net/src/session/server/test.rs index 1a52ac8170d..101013e9fa5 100644 --- a/libs/@local/harpc/net/src/session/server/test.rs +++ b/libs/@local/harpc/net/src/session/server/test.rs @@ -10,7 +10,11 @@ use bytes::{Bytes, BytesMut}; use error_stack::{Report, ResultExt}; use futures::{SinkExt, Stream, StreamExt}; use harpc_codec::json::JsonCodec; -use harpc_types::{procedure::ProcedureId, service::ServiceId, version::Version}; +use harpc_types::{ + procedure::{ProcedureDescriptor, ProcedureId}, + service::{ServiceDescriptor, ServiceId}, + version::Version, +}; use harpc_wire_protocol::{ flags::BitFlagsOp, payload::Payload, @@ -22,8 +26,6 @@ use harpc_wire_protocol::{ flags::{RequestFlag, RequestFlags}, frame::RequestFrame, header::RequestHeader, - procedure::ProcedureDescriptor, - service::ServiceDescriptor, }, response::{Response, flags::ResponseFlag}, test_utils::mock_request_id, diff --git a/libs/@local/harpc/net/src/session/server/transaction/mod.rs b/libs/@local/harpc/net/src/session/server/transaction/mod.rs index bf5541ac8b6..505346d1c1e 100644 --- a/libs/@local/harpc/net/src/session/server/transaction/mod.rs +++ b/libs/@local/harpc/net/src/session/server/transaction/mod.rs @@ -10,13 +10,13 @@ use core::{ use bytes::Bytes; use futures::{Sink, Stream, StreamExt, stream::FusedStream}; use harpc_codec::error::EncodedError; +use harpc_types::{ + procedure::ProcedureDescriptor, response_kind::ResponseKind, service::ServiceDescriptor, +}; use harpc_wire_protocol::{ flags::BitFlagsOp, - request::{ - Request, begin::RequestBegin, flags::RequestFlag, id::RequestId, - procedure::ProcedureDescriptor, service::ServiceDescriptor, - }, - response::{Response, kind::ResponseKind}, + request::{Request, begin::RequestBegin, flags::RequestFlag, id::RequestId}, + response::Response, }; use libp2p::PeerId; use tokio::{select, sync::mpsc}; diff --git a/libs/@local/harpc/net/src/session/server/transaction/test.rs b/libs/@local/harpc/net/src/session/server/transaction/test.rs index 1d728010809..8717ad47d63 100644 --- a/libs/@local/harpc/net/src/session/server/transaction/test.rs +++ b/libs/@local/harpc/net/src/session/server/transaction/test.rs @@ -2,8 +2,14 @@ use alloc::sync::Arc; use core::{num::NonZero, time::Duration}; use bytes::{BufMut, Bytes}; -use harpc_codec::error::{EncodedError, ErrorBuffer, ErrorCode}; -use harpc_types::{procedure::ProcedureId, service::ServiceId, version::Version}; +use harpc_codec::error::{EncodedError, ErrorBuffer}; +use harpc_types::{ + error_code::ErrorCode, + procedure::{ProcedureDescriptor, ProcedureId}, + response_kind::ResponseKind, + service::{ServiceDescriptor, ServiceId}, + version::Version, +}; use harpc_wire_protocol::{ flags::BitFlagsOp, payload::Payload, @@ -16,8 +22,6 @@ use harpc_wire_protocol::{ frame::RequestFrame, header::RequestHeader, id::RequestId, - procedure::ProcedureDescriptor, - service::ServiceDescriptor, }, response::{ Response, @@ -25,7 +29,6 @@ use harpc_wire_protocol::{ body::ResponseBody, flags::{ResponseFlag, ResponseFlags}, frame::ResponseFrame, - kind::ResponseKind, }, test_utils::mock_request_id, }; diff --git a/libs/@local/harpc/net/src/session/test.rs b/libs/@local/harpc/net/src/session/test.rs index 72f6125392c..6f07e3b5eab 100644 --- a/libs/@local/harpc/net/src/session/test.rs +++ b/libs/@local/harpc/net/src/session/test.rs @@ -5,8 +5,11 @@ use bytes::Bytes; use error_stack::{Report, ResultExt}; use futures::{prelude::stream, sink::SinkExt, stream::StreamExt}; use harpc_codec::json::JsonCodec; -use harpc_types::{procedure::ProcedureId, service::ServiceId, version::Version}; -use harpc_wire_protocol::request::{procedure::ProcedureDescriptor, service::ServiceDescriptor}; +use harpc_types::{ + procedure::{ProcedureDescriptor, ProcedureId}, + service::{ServiceDescriptor, ServiceId}, + version::Version, +}; use humansize::ISizeFormatter; use libp2p::{Multiaddr, multiaddr}; use tokio::{sync::Barrier, task::JoinSet, time::Instant}; diff --git a/libs/@local/harpc/net/src/session/writer/mod.rs b/libs/@local/harpc/net/src/session/writer/mod.rs index 1a46fa02edb..e75080ee7ee 100644 --- a/libs/@local/harpc/net/src/session/writer/mod.rs +++ b/libs/@local/harpc/net/src/session/writer/mod.rs @@ -3,6 +3,9 @@ mod test; use bytes::{Buf, Bytes}; use bytes_utils::SegmentedBuf; +use harpc_types::{ + procedure::ProcedureDescriptor, response_kind::ResponseKind, service::ServiceDescriptor, +}; use harpc_wire_protocol::{ flags::BitFlagsOp, payload::Payload, @@ -15,8 +18,6 @@ use harpc_wire_protocol::{ frame::RequestFrame, header::RequestHeader, id::RequestId, - procedure::ProcedureDescriptor, - service::ServiceDescriptor, }, response::{ Response, @@ -25,7 +26,6 @@ use harpc_wire_protocol::{ flags::{ResponseFlag, ResponseFlags}, frame::ResponseFrame, header::ResponseHeader, - kind::ResponseKind, }, }; use tokio::sync::mpsc; diff --git a/libs/@local/harpc/net/src/session/writer/test.rs b/libs/@local/harpc/net/src/session/writer/test.rs index dda17d25923..225806ee76d 100644 --- a/libs/@local/harpc/net/src/session/writer/test.rs +++ b/libs/@local/harpc/net/src/session/writer/test.rs @@ -1,11 +1,9 @@ use bytes::{Buf, Bytes}; +use harpc_types::response_kind::ResponseKind; use harpc_wire_protocol::{ flags::BitFlagsOp, payload::Payload, - response::{ - flags::{ResponseFlag, ResponseFlags}, - kind::ResponseKind, - }, + response::flags::{ResponseFlag, ResponseFlags}, test_utils::mock_request_id, }; use tokio::sync::mpsc; diff --git a/libs/@local/harpc/server/Cargo.toml b/libs/@local/harpc/server/Cargo.toml index 1615ef3817b..4cfef4127ac 100644 --- a/libs/@local/harpc/server/Cargo.toml +++ b/libs/@local/harpc/server/Cargo.toml @@ -20,7 +20,6 @@ tower = { workspace = true, public = true } harpc-net = { workspace = true } harpc-tower = { workspace = true } harpc-types = { workspace = true } -harpc-wire-protocol = { workspace = true } # Private third-party dependencies derive-where = { workspace = true } diff --git a/libs/@local/harpc/server/examples/account.rs b/libs/@local/harpc/server/examples/account.rs index 368acf36ff7..e2cb8aaa841 100644 --- a/libs/@local/harpc/server/examples/account.rs +++ b/libs/@local/harpc/server/examples/account.rs @@ -28,8 +28,12 @@ use harpc_tower::{ request::Request, response::{Parts, Response}, }; -use harpc_types::{procedure::ProcedureId, service::ServiceId, version::Version}; -use harpc_wire_protocol::{request::procedure::ProcedureDescriptor, response::kind::ResponseKind}; +use harpc_types::{ + procedure::{ProcedureDescriptor, ProcedureId}, + response_kind::ResponseKind, + service::ServiceId, + version::Version, +}; enum AccountProcedureId { CreateAccount, diff --git a/libs/@local/harpc/server/src/error.rs b/libs/@local/harpc/server/src/error.rs index 955249ca1c8..63769e96621 100644 --- a/libs/@local/harpc/server/src/error.rs +++ b/libs/@local/harpc/server/src/error.rs @@ -1,7 +1,6 @@ use core::error::Error; -use harpc_codec::error::ErrorCode; -use harpc_types::{service::ServiceId, version::Version}; +use harpc_types::{error_code::ErrorCode, service::ServiceId, version::Version}; #[derive( Debug, diff --git a/libs/@local/harpc/service/Cargo.toml b/libs/@local/harpc/service/Cargo.toml index 231fe554b10..b26748eacc9 100644 --- a/libs/@local/harpc/service/Cargo.toml +++ b/libs/@local/harpc/service/Cargo.toml @@ -16,7 +16,6 @@ harpc-tower = { workspace = true, public = true } # Private workspace dependencies harpc-types = { workspace = true } -harpc-wire-protocol = { workspace = true } # Private third-party dependencies frunk = "0.4.3" diff --git a/libs/@local/harpc/service/src/delegate.rs b/libs/@local/harpc/service/src/delegate.rs index 84399f339ef..6937d45e981 100644 --- a/libs/@local/harpc/service/src/delegate.rs +++ b/libs/@local/harpc/service/src/delegate.rs @@ -1,5 +1,5 @@ use harpc_tower::{body::Body, request::Request, response::Response}; -use harpc_wire_protocol::response::kind::ResponseKind; +use harpc_types::response_kind::ResponseKind; use crate::Service; diff --git a/libs/@local/harpc/service/src/role.rs b/libs/@local/harpc/service/src/role.rs index 9a8f3b39720..3ad607a988c 100644 --- a/libs/@local/harpc/service/src/role.rs +++ b/libs/@local/harpc/service/src/role.rs @@ -1,7 +1,7 @@ use core::marker::PhantomData; use harpc_tower::{body::Body, request::Request, response::Response}; -use harpc_wire_protocol::response::kind::ResponseKind; +use harpc_types::response_kind::ResponseKind; mod sealed { pub trait Sealed {} diff --git a/libs/@local/harpc/tower/Cargo.toml b/libs/@local/harpc/tower/Cargo.toml index 3c371f16c9d..35669a15aed 100644 --- a/libs/@local/harpc/tower/Cargo.toml +++ b/libs/@local/harpc/tower/Cargo.toml @@ -20,7 +20,6 @@ tower-service = { workspace = true, public = true } # Private workspace dependencies error-stack = { workspace = true } harpc-types = { workspace = true, features = ["serde"] } -harpc-wire-protocol = { workspace = true } harpc-codec = { workspace = true } # Private third-party dependencies diff --git a/libs/@local/harpc/tower/src/layer/boxed.rs b/libs/@local/harpc/tower/src/layer/boxed.rs index ff9b8a0a87f..282e6524b72 100644 --- a/libs/@local/harpc/tower/src/layer/boxed.rs +++ b/libs/@local/harpc/tower/src/layer/boxed.rs @@ -1,7 +1,7 @@ use core::task::{Context, Poll}; use bytes::Buf; -use harpc_wire_protocol::response::kind::ResponseKind; +use harpc_types::response_kind::ResponseKind; use tower::{Layer, Service, ServiceExt}; use crate::{ diff --git a/libs/@local/harpc/tower/src/layer/error.rs b/libs/@local/harpc/tower/src/layer/error.rs index e919addbe93..eff159b0a35 100644 --- a/libs/@local/harpc/tower/src/layer/error.rs +++ b/libs/@local/harpc/tower/src/layer/error.rs @@ -5,7 +5,7 @@ use core::{ use bytes::Bytes; use harpc_codec::encode::ErrorEncoder; -use harpc_wire_protocol::response::kind::ResponseKind; +use harpc_types::response_kind::ResponseKind; use tower::{Layer, Service, ServiceExt}; use crate::{ @@ -102,12 +102,14 @@ pub(crate) mod test { }; use bytes::{Buf, Bytes}; - use harpc_codec::{error::ErrorCode, json::JsonCodec}; + use harpc_codec::json::JsonCodec; use harpc_net::test_utils::mock_session_id; - use harpc_types::{procedure::ProcedureId, service::ServiceId, version::Version}; - use harpc_wire_protocol::{ - request::{procedure::ProcedureDescriptor, service::ServiceDescriptor}, - response::kind::ResponseKind, + use harpc_types::{ + error_code::ErrorCode, + procedure::{ProcedureDescriptor, ProcedureId}, + response_kind::ResponseKind, + service::{ServiceDescriptor, ServiceId}, + version::Version, }; use insta::assert_snapshot; use tokio_test::{assert_pending, assert_ready}; diff --git a/libs/@local/harpc/tower/src/layer/report.rs b/libs/@local/harpc/tower/src/layer/report.rs index 894f5f95230..4b282c9893f 100644 --- a/libs/@local/harpc/tower/src/layer/report.rs +++ b/libs/@local/harpc/tower/src/layer/report.rs @@ -3,7 +3,7 @@ use core::task::{Context, Poll}; use bytes::Bytes; use error_stack::Report; use harpc_codec::encode::ErrorEncoder; -use harpc_wire_protocol::response::kind::ResponseKind; +use harpc_types::response_kind::ResponseKind; use tower::{Layer, Service, ServiceExt}; use crate::{ @@ -99,8 +99,8 @@ mod test { use bytes::{Buf, Bytes}; use error_stack::Report; - use harpc_codec::{error::ErrorCode, json::JsonCodec}; - use harpc_wire_protocol::response::kind::ResponseKind; + use harpc_codec::json::JsonCodec; + use harpc_types::{error_code::ErrorCode, response_kind::ResponseKind}; use insta::assert_snapshot; use tokio_test::{assert_pending, assert_ready}; use tower::{Layer, Service, ServiceExt}; diff --git a/libs/@local/harpc/tower/src/net/pack.rs b/libs/@local/harpc/tower/src/net/pack.rs index 78c3dac1111..c72f853aa78 100644 --- a/libs/@local/harpc/tower/src/net/pack.rs +++ b/libs/@local/harpc/tower/src/net/pack.rs @@ -7,11 +7,8 @@ use core::{ use bytes::{Buf, BufMut, Bytes, BytesMut}; use futures::Stream; -use harpc_codec::{ - encode::ErrorEncoder, - error::{EncodedError, ErrorCode}, -}; -use harpc_wire_protocol::response::kind::ResponseKind; +use harpc_codec::{encode::ErrorEncoder, error::EncodedError}; +use harpc_types::{error_code::ErrorCode, response_kind::ResponseKind}; use crate::body::{Body, Frame}; @@ -180,12 +177,8 @@ where mod test { use bytes::{BufMut, Bytes}; use futures::{StreamExt, stream}; - use harpc_codec::{ - encode::ErrorEncoder, - error::{ErrorBuffer, ErrorCode}, - json::JsonCodec, - }; - use harpc_wire_protocol::response::kind::ResponseKind; + use harpc_codec::{encode::ErrorEncoder, error::ErrorBuffer, json::JsonCodec}; + use harpc_types::{error_code::ErrorCode, response_kind::ResponseKind}; use crate::{ body::{Frame, stream::StreamBody}, diff --git a/libs/@local/harpc/tower/src/net/unpack.rs b/libs/@local/harpc/tower/src/net/unpack.rs index 86e66f891fc..c14bfbfa187 100644 --- a/libs/@local/harpc/tower/src/net/unpack.rs +++ b/libs/@local/harpc/tower/src/net/unpack.rs @@ -8,7 +8,7 @@ use core::{ use bytes::Bytes; use futures::{Stream, StreamExt}; use harpc_net::session::client::{ErrorStream, ResponseStream, TransactionStream, ValueStream}; -use harpc_wire_protocol::response::kind::ResponseKind; +use harpc_types::response_kind::ResponseKind; use crate::body::{Body, BodyFrameResult, BodyState, Frame}; diff --git a/libs/@local/harpc/tower/src/request.rs b/libs/@local/harpc/tower/src/request.rs index 43521501049..fed4fc1f1b9 100644 --- a/libs/@local/harpc/tower/src/request.rs +++ b/libs/@local/harpc/tower/src/request.rs @@ -1,5 +1,5 @@ use harpc_net::session::server::{SessionId, transaction::TransactionContext}; -use harpc_wire_protocol::request::{procedure::ProcedureDescriptor, service::ServiceDescriptor}; +use harpc_types::{procedure::ProcedureDescriptor, service::ServiceDescriptor}; use crate::{body::Body, extensions::Extensions}; diff --git a/libs/@local/harpc/tower/src/response.rs b/libs/@local/harpc/tower/src/response.rs index 445e23ac943..bc510cb8b8a 100644 --- a/libs/@local/harpc/tower/src/response.rs +++ b/libs/@local/harpc/tower/src/response.rs @@ -2,7 +2,7 @@ use bytes::Bytes; use futures::{Stream, TryStreamExt, stream::MapOk}; use harpc_codec::error::EncodedError; use harpc_net::session::server::SessionId; -use harpc_wire_protocol::response::kind::ResponseKind; +use harpc_types::response_kind::ResponseKind; use crate::{ body::{Body, Frame, boxed::BoxBody, controlled::Controlled, full::Full, stream::StreamBody}, diff --git a/libs/@local/harpc/types/Cargo.toml b/libs/@local/harpc/types/Cargo.toml index 363cd63f97f..64cd4ce25f9 100644 --- a/libs/@local/harpc/types/Cargo.toml +++ b/libs/@local/harpc/types/Cargo.toml @@ -17,7 +17,7 @@ authors.workspace = true # Private third-party dependencies proptest = { workspace = true, optional = true } -serde = { workspace = true, features = ["derive"], optional = true } +serde = { workspace = true, features = ["derive"], optional = true, public = true } test-strategy = { workspace = true, optional = true } [features] diff --git a/libs/@local/harpc/types/src/error_code.rs b/libs/@local/harpc/types/src/error_code.rs new file mode 100644 index 00000000000..44c2b75f238 --- /dev/null +++ b/libs/@local/harpc/types/src/error_code.rs @@ -0,0 +1,131 @@ +use core::num::NonZero; + +macro_rules! non_zero { + ($n:expr) => {{ + // ensure that the value is not 0, in case it is, panic during compile time + const { + assert!($n != 0, "value must not be 0"); + } + + #[expect(unsafe_code, reason = "checked that it is never 0")] + // SAFETY: $value is not 0 + unsafe { + NonZero::new_unchecked($n) + } + }}; +} + +// we use a macro here to define the error codes, as the code is quite repetetive and also error +// prone, we might not be able to increment values correctly, another problem is that rustfmt will +// reorder the constants, making keeping tracks of the ids harder than it should be. +macro_rules! define_error_code_consts { + ($( + $(#[$meta:meta])* + $base:literal => [$( + $(#[$name_meta:meta])* + $name:ident + ),+] + ),*) => { + $( + $(#[$meta])* + impl ErrorCode { + $( + $(#[$name_meta])* + /// + /// + /// **Error Code**: ` + #[doc = stringify!($base)] + #[doc = "+"] + #[doc = stringify!(${index(0)})] + #[doc = "`"] + pub const $name: Self = Self(non_zero!($base + ${index(0)})); + )+ + } + )* + }; +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))] +pub struct ErrorCode(NonZero); + +impl ErrorCode { + #[must_use] + pub const fn new(value: NonZero) -> Self { + Self(value) + } + + #[must_use] + pub const fn value(self) -> NonZero { + self.0 + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for ErrorCode { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let value = u16::deserialize(deserializer)?; + + NonZero::new(value) + .map(Self) + .ok_or_else(|| serde::de::Error::custom("value must not be 0")) + } +} + +define_error_code_consts! { + // 0xFE_xx = client errors + /// Errors initiated by the client, but that occur on the server. + /// + /// These errors are issued on the higher-level tower implementation. + 0xFE_10 => [ + /// The combination of service and version requirement could not be found on the server. + /// + /// The HTTP equivalent is 404 Not Found. + NOT_FOUND + ], + // 0xFF_xx = server errors + /// Errors that occur in a session and are issued by the server. + /// + /// These errors are issued on the lower-level network layer. + 0xFF_00 => [ + /// Server is shutting down. + /// + /// The server is in the process of shutting down and no longer acceptts new connections. + CONNECTION_SHUTDOWN, + /// Connection transaction limit reached. + /// + /// The total count of concurrent transaction per connection has been reached. + CONNECTION_TRANSACTION_LIMIT_REACHED, + /// Instance transaction limit reached. + /// + /// The total count of concurrent transaction per server node has been reached. + INSTANCE_TRANSACTION_LIMIT_REACHED, + /// Transaction is lagging behind. + /// + /// The client sent too many packets that haven't been processed by the server yet, + /// which lead to packets dropping and the transaction being cancelled. + TRANSACTION_LAGGING + ], + /// Errors that occur due to malformed payloads in the tower layer. + 0xFF_10 => [ + /// Encoded error encountered an invalid error tag. + /// + /// The returned payload for an encoded error does not have a valid error tag to distinguish + /// between the different error encodings and could therefore not be properly encoded. + /// + /// This is a fault in the implementation of the server, either in the `codec` or + /// the `tower` layer. + PACK_INVALID_ERROR_TAG + ], + /// Generic server errors. + 0xFF_F0 => [ + /// An internal server error occurred. + /// + /// An unknown error occurred on the server. + INTERNAL_SERVER_ERROR + ] +} diff --git a/libs/@local/harpc/types/src/lib.rs b/libs/@local/harpc/types/src/lib.rs index 4fc8ac9022b..d56d6a65b88 100644 --- a/libs/@local/harpc/types/src/lib.rs +++ b/libs/@local/harpc/types/src/lib.rs @@ -1,3 +1,7 @@ +#![feature(macro_metavar_expr, never_type)] + +pub mod error_code; pub mod procedure; +pub mod response_kind; pub mod service; pub mod version; diff --git a/libs/@local/harpc/types/src/procedure.rs b/libs/@local/harpc/types/src/procedure.rs index 6b5526c6df3..940d542072f 100644 --- a/libs/@local/harpc/types/src/procedure.rs +++ b/libs/@local/harpc/types/src/procedure.rs @@ -20,3 +20,10 @@ impl ProcedureId { self.0 & 0xF000 == 0xF000 } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))] +pub struct ProcedureDescriptor { + pub id: ProcedureId, +} diff --git a/libs/@local/harpc/types/src/response_kind.rs b/libs/@local/harpc/types/src/response_kind.rs new file mode 100644 index 00000000000..c0a98d26506 --- /dev/null +++ b/libs/@local/harpc/types/src/response_kind.rs @@ -0,0 +1,50 @@ +use core::num::NonZero; + +use crate::error_code::ErrorCode; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))] +pub enum ResponseKind { + Ok, + Err(ErrorCode), +} + +impl ResponseKind { + #[must_use] + pub const fn is_ok(self) -> bool { + matches!(self, Self::Ok) + } + + #[must_use] + pub const fn is_err(self) -> bool { + matches!(self, Self::Err(_)) + } +} + +impl From for ResponseKind { + fn from(value: u16) -> Self { + NonZero::new(value).map_or(Self::Ok, |value| Self::Err(ErrorCode::new(value))) + } +} + +impl AsRef for ResponseKind { + fn as_ref(&self) -> &Self { + self + } +} + +impl From for ResponseKind { + fn from(never: !) -> Self { + never + } +} + +impl From for u16 { + fn from(kind: ResponseKind) -> Self { + match kind { + ResponseKind::Ok => 0, + ResponseKind::Err(code) => code.value().get(), + } + } +} diff --git a/libs/@local/harpc/types/src/service.rs b/libs/@local/harpc/types/src/service.rs index 85655002480..4700482bc14 100644 --- a/libs/@local/harpc/types/src/service.rs +++ b/libs/@local/harpc/types/src/service.rs @@ -1,3 +1,5 @@ +use crate::version::Version; + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))] @@ -20,3 +22,11 @@ impl ServiceId { self.0 & 0xF000 == 0xF000 } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))] +pub struct ServiceDescriptor { + pub id: ServiceId, + pub version: Version, +} diff --git a/libs/@local/harpc/wire-protocol/Cargo.toml b/libs/@local/harpc/wire-protocol/Cargo.toml index 4b133300044..cf0b5cd8d6e 100644 --- a/libs/@local/harpc/wire-protocol/Cargo.toml +++ b/libs/@local/harpc/wire-protocol/Cargo.toml @@ -27,7 +27,6 @@ thiserror = { workspace = true } proptest = { workspace = true } test-strategy = { workspace = true } harpc-types = { workspace = true, features = ["proptest"] } -harpc-codec = { workspace = true, features = ["proptest"] } expect-test = { workspace = true } similar-asserts = { workspace = true } diff --git a/libs/@local/harpc/wire-protocol/src/request/begin.rs b/libs/@local/harpc/wire-protocol/src/request/begin.rs index 83564faf519..f99171ca6ab 100644 --- a/libs/@local/harpc/wire-protocol/src/request/begin.rs +++ b/libs/@local/harpc/wire-protocol/src/request/begin.rs @@ -1,7 +1,7 @@ use bytes::{Buf, BufMut}; use error_stack::{Result, ResultExt}; +use harpc_types::{procedure::ProcedureDescriptor, service::ServiceDescriptor}; -use super::{procedure::ProcedureDescriptor, service::ServiceDescriptor}; use crate::{ codec::{Buffer, BufferError, Decode, Encode}, payload::Payload, @@ -73,14 +73,16 @@ impl Decode for RequestBegin { #[cfg(test)] mod test { use expect_test::expect; - use harpc_types::{procedure::ProcedureId, service::ServiceId, version::Version}; + use harpc_types::{ + procedure::{ProcedureDescriptor, ProcedureId}, + service::{ServiceDescriptor, ServiceId}, + version::Version, + }; use crate::{ codec::test::{assert_codec, assert_decode, assert_encode}, payload::Payload, - request::{ - begin::RequestBegin, procedure::ProcedureDescriptor, service::ServiceDescriptor, - }, + request::begin::RequestBegin, }; static EXAMPLE_REQUEST: RequestBegin = RequestBegin { diff --git a/libs/@local/harpc/wire-protocol/src/request/body.rs b/libs/@local/harpc/wire-protocol/src/request/body.rs index 9779f4f94e5..f9af4500069 100644 --- a/libs/@local/harpc/wire-protocol/src/request/body.rs +++ b/libs/@local/harpc/wire-protocol/src/request/body.rs @@ -104,16 +104,17 @@ impl Decode for RequestBody { mod test { #![expect(clippy::needless_raw_strings)] use expect_test::expect; - use harpc_types::{procedure::ProcedureId, service::ServiceId, version::Version}; + use harpc_types::{ + procedure::{ProcedureDescriptor, ProcedureId}, + service::{ServiceDescriptor, ServiceId}, + version::Version, + }; use super::{RequestBody, RequestBodyContext}; use crate::{ codec::test::{assert_codec, assert_decode, assert_encode, encode_value}, payload::Payload, - request::{ - begin::RequestBegin, body::RequestVariant, frame::RequestFrame, - procedure::ProcedureDescriptor, service::ServiceDescriptor, - }, + request::{begin::RequestBegin, body::RequestVariant, frame::RequestFrame}, }; static EXAMPLE_BEGIN: RequestBegin = RequestBegin { diff --git a/libs/@local/harpc/wire-protocol/src/request/mod.rs b/libs/@local/harpc/wire-protocol/src/request/mod.rs index 8c023554691..4c782a29ce6 100644 --- a/libs/@local/harpc/wire-protocol/src/request/mod.rs +++ b/libs/@local/harpc/wire-protocol/src/request/mod.rs @@ -135,7 +135,11 @@ impl Decode for Request { mod test { #![expect(clippy::needless_raw_strings)] use expect_test::expect; - use harpc_types::{procedure::ProcedureId, service::ServiceId, version::Version}; + use harpc_types::{ + procedure::{ProcedureDescriptor, ProcedureId}, + service::{ServiceDescriptor, ServiceId}, + version::Version, + }; use super::id::test_utils::mock_request_id; use crate::{ @@ -150,8 +154,6 @@ mod test { flags::{RequestFlag, RequestFlags}, frame::RequestFrame, header::RequestHeader, - procedure::ProcedureDescriptor, - service::ServiceDescriptor, }, }; diff --git a/libs/@local/harpc/wire-protocol/src/request/procedure.rs b/libs/@local/harpc/wire-protocol/src/request/procedure.rs index a05c2c2c4a0..0e80eff967e 100644 --- a/libs/@local/harpc/wire-protocol/src/request/procedure.rs +++ b/libs/@local/harpc/wire-protocol/src/request/procedure.rs @@ -1,15 +1,9 @@ use bytes::{Buf, BufMut}; use error_stack::Result; -use harpc_types::procedure::ProcedureId; +use harpc_types::procedure::{ProcedureDescriptor, ProcedureId}; use crate::codec::{Buffer, BufferError, Decode, Encode}; -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(test, derive(test_strategy::Arbitrary))] -pub struct ProcedureDescriptor { - pub id: ProcedureId, -} - impl Encode for ProcedureDescriptor { type Error = BufferError; diff --git a/libs/@local/harpc/wire-protocol/src/request/service.rs b/libs/@local/harpc/wire-protocol/src/request/service.rs index 0c0695335f8..9d34e3799d3 100644 --- a/libs/@local/harpc/wire-protocol/src/request/service.rs +++ b/libs/@local/harpc/wire-protocol/src/request/service.rs @@ -1,16 +1,12 @@ use bytes::{Buf, BufMut}; use error_stack::Result; -use harpc_types::{service::ServiceId, version::Version}; +use harpc_types::{ + service::{ServiceDescriptor, ServiceId}, + version::Version, +}; use crate::codec::{Buffer, BufferError, Decode, Encode}; -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(test, derive(test_strategy::Arbitrary))] -pub struct ServiceDescriptor { - pub id: ServiceId, - pub version: Version, -} - impl Encode for ServiceDescriptor { type Error = BufferError; diff --git a/libs/@local/harpc/wire-protocol/src/response/begin.rs b/libs/@local/harpc/wire-protocol/src/response/begin.rs index e2d27d6781a..f0c3d9f98f3 100644 --- a/libs/@local/harpc/wire-protocol/src/response/begin.rs +++ b/libs/@local/harpc/wire-protocol/src/response/begin.rs @@ -1,7 +1,7 @@ use bytes::{Buf, BufMut}; use error_stack::{Result, ResultExt}; +use harpc_types::response_kind::ResponseKind; -use super::kind::ResponseKind; use crate::{ codec::{Buffer, BufferError, Decode, Encode}, payload::Payload, @@ -64,11 +64,12 @@ impl Decode for ResponseBegin { mod test { #![expect(clippy::needless_raw_strings)] use expect_test::expect; + use harpc_types::response_kind::ResponseKind; use crate::{ codec::test::{assert_codec, assert_decode, assert_encode}, payload::Payload, - response::{begin::ResponseBegin, kind::ResponseKind}, + response::begin::ResponseBegin, }; #[test] diff --git a/libs/@local/harpc/wire-protocol/src/response/body.rs b/libs/@local/harpc/wire-protocol/src/response/body.rs index 6f77723b35c..8c14a2a17e1 100644 --- a/libs/@local/harpc/wire-protocol/src/response/body.rs +++ b/libs/@local/harpc/wire-protocol/src/response/body.rs @@ -96,6 +96,7 @@ impl Decode for ResponseBody { mod test { #![expect(clippy::needless_raw_strings)] use expect_test::expect; + use harpc_types::response_kind::ResponseKind; use crate::{ codec::test::{assert_codec, assert_decode, assert_encode}, @@ -104,7 +105,6 @@ mod test { begin::ResponseBegin, body::{ResponseBody, ResponseBodyContext, ResponseVariant}, frame::ResponseFrame, - kind::ResponseKind, }, }; diff --git a/libs/@local/harpc/wire-protocol/src/response/kind.rs b/libs/@local/harpc/wire-protocol/src/response/kind.rs index ffb49238b8c..05cdb229b3e 100644 --- a/libs/@local/harpc/wire-protocol/src/response/kind.rs +++ b/libs/@local/harpc/wire-protocol/src/response/kind.rs @@ -1,57 +1,9 @@ -use core::num::NonZero; - use bytes::{Buf, BufMut}; use error_stack::Result; -use harpc_codec::error::ErrorCode; +use harpc_types::response_kind::ResponseKind; use crate::codec::{Buffer, BufferError, Decode, Encode}; -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(test, derive(test_strategy::Arbitrary))] -pub enum ResponseKind { - Ok, - Err(ErrorCode), -} - -impl ResponseKind { - #[must_use] - pub const fn is_ok(self) -> bool { - matches!(self, Self::Ok) - } - - #[must_use] - pub const fn is_err(self) -> bool { - matches!(self, Self::Err(_)) - } -} - -impl From for ResponseKind { - fn from(value: u16) -> Self { - NonZero::new(value).map_or(Self::Ok, |value| Self::Err(ErrorCode::new(value))) - } -} - -impl AsRef for ResponseKind { - fn as_ref(&self) -> &Self { - self - } -} - -impl From for ResponseKind { - fn from(never: !) -> Self { - never - } -} - -impl From for u16 { - fn from(kind: ResponseKind) -> Self { - match kind { - ResponseKind::Ok => 0, - ResponseKind::Err(code) => code.value().get(), - } - } -} - impl Encode for ResponseKind { type Error = BufferError; @@ -81,12 +33,9 @@ mod test { use core::num::NonZero; use expect_test::expect; - use harpc_codec::error::ErrorCode; + use harpc_types::{error_code::ErrorCode, response_kind::ResponseKind}; - use crate::{ - codec::test::{assert_codec, assert_decode, assert_encode}, - response::kind::ResponseKind, - }; + use crate::codec::test::{assert_codec, assert_decode, assert_encode}; #[test] fn encode() { diff --git a/libs/@local/harpc/wire-protocol/src/response/mod.rs b/libs/@local/harpc/wire-protocol/src/response/mod.rs index 2494768e6a4..8af379256a0 100644 --- a/libs/@local/harpc/wire-protocol/src/response/mod.rs +++ b/libs/@local/harpc/wire-protocol/src/response/mod.rs @@ -140,6 +140,7 @@ impl Decode for Response { mod test { #![expect(clippy::needless_raw_strings)] use expect_test::expect; + use harpc_types::response_kind::ResponseKind; use super::{flags::ResponseFlags, header::ResponseHeader}; use crate::{ @@ -150,7 +151,7 @@ mod test { request::id::test_utils::mock_request_id, response::{ Response, begin::ResponseBegin, body::ResponseBody, flags::ResponseFlag, - frame::ResponseFrame, kind::ResponseKind, + frame::ResponseFrame, }, };