Skip to main content

raftlog_protobuf/
state.rs

1//! Encoders and decoders for the constituents defined in `raftlog::state` module.
2use bytecodec::ErrorKind;
3use protobuf_codec::field::num::{F1, F2, F3};
4use protobuf_codec::field::{FieldDecoder, FieldEncoder, Fields, MaybeDefault, Repeated};
5use protobuf_codec::message::{MessageDecoder, MessageEncoder};
6use protobuf_codec::scalar::{
7    StringDecoder, StringEncoder, Uint32Decoder, Uint32Encoder, Uint64Decoder, Uint64Encoder,
8};
9use raftlog::cluster::{ClusterConfig, ClusterState};
10use raftlog::election::Ballot;
11use raftlog::node::NodeId;
12
13/// Decoder for `Ballot`.
14#[derive(Debug, Default)]
15pub struct BallotDecoder {
16    inner: MessageDecoder<
17        Fields<(
18            MaybeDefault<FieldDecoder<F1, Uint64Decoder>>,
19            MaybeDefault<FieldDecoder<F2, StringDecoder>>,
20        )>,
21    >,
22}
23impl_message_decode!(BallotDecoder, Ballot, |t: (u64, String)| Ok(Ballot {
24    term: t.0.into(),
25    voted_for: t.1.into()
26}));
27
28/// Encoder for `Ballot`.
29#[derive(Debug, Default)]
30pub struct BallotEncoder {
31    inner: MessageEncoder<
32        Fields<(
33            FieldEncoder<F1, Uint64Encoder>,
34            FieldEncoder<F2, StringEncoder>,
35        )>,
36    >,
37}
38impl_sized_message_encode!(BallotEncoder, Ballot, |item: Self::Item| (
39    item.term.as_u64(),
40    item.voted_for.into_string()
41));
42
43/// Decoder for `ClusterConfig`.
44#[derive(Debug, Default)]
45pub struct ClusterConfigDecoder {
46    inner: MessageDecoder<
47        Fields<(
48            Repeated<FieldDecoder<F1, StringDecoder>, Vec<String>>,
49            Repeated<FieldDecoder<F2, StringDecoder>, Vec<String>>,
50            MaybeDefault<FieldDecoder<F3, Uint32Decoder>>,
51        )>,
52    >,
53}
54impl_message_decode!(ClusterConfigDecoder, ClusterConfig, |t: (
55    Vec<_>,
56    Vec<_>,
57    u32
58)| Ok(
59    ClusterConfig::with_state(
60        t.0.into_iter().map(NodeId::from).collect(),
61        t.1.into_iter().map(NodeId::from).collect(),
62        match t.2 {
63            0 => ClusterState::Stable,
64            1 => ClusterState::CatchUp,
65            2 => ClusterState::Joint,
66            n => track_panic!(ErrorKind::InvalidInput, "Unknown cluster state: {}", n),
67        }
68    )
69));
70
71/// Encoder for `ClusterConfig`.
72#[derive(Debug, Default)]
73pub struct ClusterConfigEncoder {
74    inner: MessageEncoder<
75        Fields<(
76            Repeated<FieldEncoder<F1, StringEncoder>, Vec<String>>,
77            Repeated<FieldEncoder<F2, StringEncoder>, Vec<String>>,
78            MaybeDefault<FieldEncoder<F3, Uint32Encoder>>,
79        )>,
80    >,
81}
82impl_message_encode!(ClusterConfigEncoder, ClusterConfig, |item: Self::Item| (
83    item.new_members()
84        .iter()
85        .map(|n| n.clone().into_string())
86        .collect(),
87    item.old_members()
88        .iter()
89        .map(|n| n.clone().into_string())
90        .collect(),
91    match item.state() {
92        ClusterState::Stable => 0,
93        ClusterState::CatchUp => 1,
94        ClusterState::Joint => 2,
95    }
96));