Skip to main content

krabka_protocol/
codec.rs

1use bytes::{Buf, BufMut};
2
3use crate::ProtocolError;
4
5/// Encode a Kafka wire-protocol value into a buffer at the given protocol version.
6///
7/// `version` is the message-level version negotiated with `ApiVersionsRequest`.
8/// Implementations must produce bytes that are byte-equal to the upstream JVM
9/// `kafka-clients` implementation for the same `(message_type, version, value)`.
10pub trait Encode {
11    /// # Errors
12    /// Returns the underlying protocol error when input is truncated, contains an invalid length or tag, or cannot be encoded for the selected version.
13    fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError>;
14
15    /// Size in bytes that `encode` will write.
16    ///
17    /// This must equal the actual count.
18    fn encoded_len(&self, version: i16) -> usize;
19}
20
21/// Decode a Kafka wire-protocol value from a buffer at the given protocol version.
22///
23/// The `'de` lifetime is the lifetime the decoded value may borrow from the input.
24/// Owned-flavor types implement `Decode<'de>` for any `'de`, because their output
25/// is `'static`. Borrowed-flavor types implement `Decode<'de>` where `Self: 'de`.
26pub trait Decode<'de>: Sized {
27    /// # Errors
28    /// Returns the underlying protocol error when input is truncated, contains an invalid length or tag, or cannot be encoded for the selected version.
29    fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError>;
30}
31
32/// Like `Decode`, but for the borrowed, zero-copy flavors.
33///
34/// This trait needs a contiguous buffer, because borrowed values reference slices
35/// of it.
36pub trait DecodeBorrow<'de>: Sized + 'de {
37    /// # Errors
38    /// Returns the underlying protocol error when input is truncated, contains an invalid length or tag, or cannot be encoded for the selected version.
39    fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError>;
40}
41
42/// Implemented by every generated Request struct in `krabka-protocol`.
43///
44/// The `krabka-protocol-codegen` crate emits this impl for every Request type.
45/// The trait gives the client the dispatch information it needs: the api key, the
46/// version range, and the response type.
47pub trait ProtocolRequest: Encode {
48    /// Kafka API key for this request.
49    const API_KEY: i16;
50    /// Minimum protocol version this Rust type supports.
51    const MIN_VERSION: i16;
52    /// Maximum protocol version this Rust type can encode and decode.
53    ///
54    /// This includes a version that the schema marks
55    /// `latestVersionUnstable`, so a broker can still decode that version
56    /// when it enables unstable versions. A client picks its version with
57    /// [`Self::LATEST_STABLE_VERSION`].
58    const MAX_VERSION: i16;
59    /// Highest protocol version that a client can send.
60    ///
61    /// This is Kafka's `ApiKeys.latestVersion(false)`. It is
62    /// `MAX_VERSION - 1` when the schema sets `latestVersionUnstable`, and
63    /// `MAX_VERSION` otherwise. A value below `MIN_VERSION` means that the
64    /// request has no stable version.
65    const LATEST_STABLE_VERSION: i16;
66    /// First version that uses flexible framing from KIP-482.
67    /// This is `i16::MAX` for never-flexible messages.
68    const FLEXIBLE_MIN: i16;
69
70    /// Matching response type from `krabka-protocol`.
71    type Response: for<'de> Decode<'de>;
72}