use prost::Message;
use crate::broker::protocol_v2::{
GetBrokerHttpEndpointRequest, GetBrokerHttpEndpointResponse,
};
#[derive(Debug, Clone, Copy)]
pub struct BrokerHttpEndpoint {
pub port: u16,
pub pid: u32,
}
impl BrokerHttpEndpoint {
pub fn to_response(self) -> GetBrokerHttpEndpointResponse {
GetBrokerHttpEndpointResponse {
port: self.port as u32,
pid: self.pid,
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum GetHttpEndpointError {
#[error("decode GetBrokerHttpEndpointRequest: {0}")]
Decode(#[from] prost::DecodeError),
#[error("encode GetBrokerHttpEndpointResponse: {0}")]
Encode(#[from] prost::EncodeError),
}
pub fn decode_request_and_dispatch(
request_body: &[u8],
endpoint: BrokerHttpEndpoint,
) -> Result<Vec<u8>, GetHttpEndpointError> {
let _request = GetBrokerHttpEndpointRequest::decode(request_body)?;
let response = endpoint.to_response();
let mut body = Vec::with_capacity(response.encoded_len());
response.encode(&mut body)?;
Ok(body)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn to_response_carries_port_and_pid() {
let resp = BrokerHttpEndpoint {
port: 8765,
pid: 12_345,
}
.to_response();
assert_eq!(resp.port, 8765);
assert_eq!(resp.pid, 12_345);
}
#[test]
fn dispatch_round_trip_with_empty_request() {
let req = GetBrokerHttpEndpointRequest::default();
let mut body = Vec::with_capacity(req.encoded_len());
req.encode(&mut body).expect("encode request");
let resp_body = decode_request_and_dispatch(
&body,
BrokerHttpEndpoint {
port: 4242,
pid: 99_999,
},
)
.expect("dispatch succeeds");
let resp =
GetBrokerHttpEndpointResponse::decode(resp_body.as_slice()).expect("decode response");
assert_eq!(resp.port, 4242);
assert_eq!(resp.pid, 99_999);
}
#[test]
fn dispatch_rejects_malformed_request_body() {
let err = decode_request_and_dispatch(
&[0xFF; 4],
BrokerHttpEndpoint {
port: 4242,
pid: 99_999,
},
)
.expect_err("malformed request body should be rejected");
match err {
GetHttpEndpointError::Decode(_) => {}
other => panic!("expected Decode error, got: {other:?}"),
}
}
}