vector/sources/opentelemetry/
reply.rs

1use bytes::BytesMut;
2use http::{header::CONTENT_TYPE, HeaderValue};
3use prost::Message;
4use warp::{reply::Response, Reply};
5
6use super::status::Status;
7
8/// If a type fails to be encoded as Protobuf, the error is logged at the
9/// `error` level, and the returned `impl Reply` will be an empty
10/// `500 Internal Server Error` response.
11pub fn protobuf<T>(val: T) -> Protobuf
12where
13    T: Message,
14{
15    let mut buf = BytesMut::with_capacity(1024);
16    Protobuf {
17        inner: val.encode(&mut buf).map(|_| buf.to_vec()).map_err(|err| {
18            error!("Failed to encode value: {}", err);
19        }),
20    }
21}
22
23/// A Protobuf formatted reply.
24#[allow(missing_debug_implementations)]
25pub struct Protobuf {
26    inner: Result<Vec<u8>, ()>,
27}
28
29impl Reply for Protobuf {
30    #[inline]
31    fn into_response(self) -> Response {
32        match self.inner {
33            Ok(body) => {
34                let mut res = Response::new(body.into());
35                res.headers_mut().insert(
36                    CONTENT_TYPE,
37                    HeaderValue::from_static("application/x-protobuf"),
38                );
39                res
40            }
41            Err(()) => {
42                let status = Status {
43                    message: "Failed to encode error message".into(),
44                    ..Default::default()
45                };
46                let mut res = Response::new(status.encode_to_vec().into());
47                res.headers_mut().insert(
48                    CONTENT_TYPE,
49                    HeaderValue::from_static("application/x-protobuf"),
50                );
51                res
52            }
53        }
54    }
55}