Skip to main content

krabka_raft/kraft/transport/
api_key.rs

1//! KIP-595 api keys used by the engine's peer sends.
2//!
3//! The engine tags every outbound body with one of these `api_key` values, and
4//! the inbound dispatch routes on the same numbers.
5
6pub const FETCH: i16 = 1;
7pub const VOTE: i16 = 52;
8pub const BEGIN_QUORUM_EPOCH: i16 = 53;
9pub const END_QUORUM_EPOCH: i16 = 54;
10pub const FETCH_SNAPSHOT: i16 = 59;
11
12/// The five KIP-595 peer RPCs, keyed by their Kafka api key.
13///
14/// Every table that treats the peer apis alike (dispatch, authorization,
15/// version negotiation) matches on this rather than restating the key list.
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17#[repr(i16)]
18pub enum PeerApi {
19    Fetch = FETCH,
20    Vote = VOTE,
21    BeginQuorumEpoch = BEGIN_QUORUM_EPOCH,
22    EndQuorumEpoch = END_QUORUM_EPOCH,
23    FetchSnapshot = FETCH_SNAPSHOT,
24}
25
26impl PeerApi {
27    /// The peer api with Kafka api key `key`, or `None` for any other api.
28    #[must_use]
29    pub const fn from_api_key(key: i16) -> Option<Self> {
30        Some(match key {
31            FETCH => Self::Fetch,
32            VOTE => Self::Vote,
33            BEGIN_QUORUM_EPOCH => Self::BeginQuorumEpoch,
34            END_QUORUM_EPOCH => Self::EndQuorumEpoch,
35            FETCH_SNAPSHOT => Self::FetchSnapshot,
36            _ => return None,
37        })
38    }
39
40    /// The Kafka api key.
41    #[must_use]
42    pub const fn api_key(self) -> i16 { self as i16 }
43
44    /// The version the engine encodes this api's body at, the newest it
45    /// speaks.
46    #[must_use]
47    pub const fn version(self) -> i16 {
48        use super::wire::{
49            FETCH_SNAPSHOT_VERSION, FETCH_VERSION, QUORUM_EPOCH_VERSION, VOTE_VERSION,
50        };
51        match self {
52            Self::Fetch => FETCH_VERSION,
53            Self::Vote => VOTE_VERSION,
54            Self::BeginQuorumEpoch | Self::EndQuorumEpoch => QUORUM_EPOCH_VERSION,
55            Self::FetchSnapshot => FETCH_SNAPSHOT_VERSION,
56        }
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[yare::parameterized(
65        fetch = { FETCH, Some(PeerApi::Fetch) },
66        vote = { VOTE, Some(PeerApi::Vote) },
67        begin_quorum_epoch = { BEGIN_QUORUM_EPOCH, Some(PeerApi::BeginQuorumEpoch) },
68        end_quorum_epoch = { END_QUORUM_EPOCH, Some(PeerApi::EndQuorumEpoch) },
69        fetch_snapshot = { FETCH_SNAPSHOT, Some(PeerApi::FetchSnapshot) },
70        non_peer_key_zero = { 0, None },
71        non_peer_key_between_ranges = { 55, None },
72    )]
73    fn peer_api_round_trips_through_its_api_key(key: i16, expected: Option<PeerApi>) {
74        let actual = PeerApi::from_api_key(key);
75        assert2::assert!(actual == expected);
76        if let Some(api) = expected {
77            assert2::assert!(api.api_key() == key);
78        }
79    }
80}