#![doc = include_str!("../README.md")]
#![allow(clippy::all)]
pub mod v1 {
tonic::include_proto!("tsoracle.v1");
use prost::Message;
use tonic::Status;
use tonic::metadata::MetadataKey;
pub const LEADER_HINT_TRAILER_KEY: &str = "tsoracle-leader-hint-bin";
pub enum LeaderHintLookup {
Absent,
Decoded(LeaderHint),
Malformed,
}
pub fn decode_leader_hint(status: &Status) -> LeaderHintLookup {
let Ok(key) = MetadataKey::from_bytes(LEADER_HINT_TRAILER_KEY.as_bytes()) else {
return LeaderHintLookup::Absent;
};
let Some(value) = status.metadata().get_bin(key) else {
return LeaderHintLookup::Absent;
};
let Ok(bytes) = value.to_bytes() else {
return LeaderHintLookup::Malformed;
};
match LeaderHint::decode(bytes.as_ref()) {
Ok(hint) => LeaderHintLookup::Decoded(hint),
Err(_) => LeaderHintLookup::Malformed,
}
}
}
#[cfg(feature = "reflection")]
pub const FILE_DESCRIPTOR_SET: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/tsoracle_descriptor.bin"));
#[cfg(test)]
mod tests {
use super::v1::*;
use prost::Message;
use tonic::Status;
use tonic::metadata::{BinaryMetadataKey, BinaryMetadataValue};
#[test]
fn message_types_exist() {
let _ = GetTsRequest { count: 1 };
let _ = GetTsResponse {
physical_ms: 0,
logical_start: 0,
count: 0,
epoch_hi: 0,
epoch_lo: 0,
};
let _ = LeaderHint {
leader_endpoint: Some("127.0.0.1:50551".into()),
leader_epoch: Some(EpochWire { hi: 0, lo: 1 }),
};
}
#[test]
fn leader_epoch_round_trips_as_a_single_unit() {
let with_epoch = LeaderHint {
leader_endpoint: Some("127.0.0.1:50551".into()),
leader_epoch: Some(EpochWire { hi: 1, lo: 3 }),
};
let decoded = LeaderHint::decode(with_epoch.encode_to_vec().as_ref()).unwrap();
assert_eq!(decoded.leader_epoch, Some(EpochWire { hi: 1, lo: 3 }));
let without_epoch = LeaderHint {
leader_endpoint: Some("127.0.0.1:50551".into()),
leader_epoch: None,
};
let decoded = LeaderHint::decode(without_epoch.encode_to_vec().as_ref()).unwrap();
assert_eq!(decoded.leader_epoch, None);
}
#[test]
fn decode_leader_hint_returns_absent_when_no_trailer_present() {
let status = Status::failed_precondition("not leader");
assert!(matches!(
decode_leader_hint(&status),
LeaderHintLookup::Absent
));
}
#[test]
fn decode_leader_hint_returns_malformed_on_bad_protobuf() {
let mut status = Status::failed_precondition("not leader");
let key = BinaryMetadataKey::from_bytes(LEADER_HINT_TRAILER_KEY.as_bytes())
.expect("LEADER_HINT_TRAILER_KEY must be a valid binary metadata key");
let value = BinaryMetadataValue::from_bytes(&[0xff, 0xff, 0xff, 0xff]);
status.metadata_mut().insert_bin(key, value);
assert!(matches!(
decode_leader_hint(&status),
LeaderHintLookup::Malformed
));
}
#[test]
fn decode_leader_hint_decodes_well_formed_trailer() {
let mut status = Status::failed_precondition("not leader");
let key = BinaryMetadataKey::from_bytes(LEADER_HINT_TRAILER_KEY.as_bytes())
.expect("LEADER_HINT_TRAILER_KEY must be a valid binary metadata key");
let hint = LeaderHint {
leader_endpoint: Some("10.0.0.7:50551".into()),
leader_epoch: Some(EpochWire { hi: 0, lo: 42 }),
};
let value = BinaryMetadataValue::from_bytes(&hint.encode_to_vec());
status.metadata_mut().insert_bin(key, value);
match decode_leader_hint(&status) {
LeaderHintLookup::Decoded(decoded) => {
assert_eq!(decoded.leader_endpoint, hint.leader_endpoint);
assert_eq!(decoded.leader_epoch, hint.leader_epoch);
}
other => panic!(
"expected Decoded(_), got something else: {}",
match other {
LeaderHintLookup::Absent => "Absent",
LeaderHintLookup::Malformed => "Malformed",
LeaderHintLookup::Decoded(_) => unreachable!(),
}
),
}
}
}