medea_control_api_proto/grpc/convert/
callback.rs

1//! Conversions between [`CallbackApi`] types and the ones generated from
2//! `callback.proto` [gRPC] spec.
3//!
4//! [`CallbackApi`]: crate::CallbackApi
5//! [gRPC]: https://grpc.io
6
7use time::{
8    OffsetDateTime as DateTime, format_description::well_known::Rfc3339,
9};
10
11use crate::{
12    callback::{Event, OnJoinEvent, OnLeaveEvent, OnLeaveReason, Request},
13    grpc::{ProtobufError, callback as proto},
14};
15
16impl TryFrom<proto::Request> for Request {
17    type Error = ProtobufError;
18
19    fn try_from(value: proto::Request) -> Result<Self, Self::Error> {
20        Ok(Self {
21            fid: value.fid.parse()?,
22            event: value
23                .event
24                .ok_or_else(|| ProtobufError::NoElementForId(value.fid.into()))?
25                .into(),
26            at: DateTime::parse(&value.at, &Rfc3339)?,
27        })
28    }
29}
30
31impl From<Request> for proto::Request {
32    fn from(req: Request) -> Self {
33        Self {
34            fid: req.fid.to_string(),
35            at: req.at.format(&Rfc3339).unwrap_or_else(|e| unreachable!("{e}")),
36            event: Some(req.event.into()),
37        }
38    }
39}
40
41impl From<proto::request::Event> for Event {
42    fn from(ev: proto::request::Event) -> Self {
43        use proto::request::Event;
44
45        match ev {
46            Event::OnJoin(on_join) => Self::OnJoin(on_join.into()),
47            Event::OnLeave(on_leave) => Self::OnLeave(on_leave.into()),
48        }
49    }
50}
51
52impl From<Event> for proto::request::Event {
53    fn from(ev: Event) -> Self {
54        match ev {
55            Event::OnJoin(on_join) => Self::OnJoin(on_join.into()),
56            Event::OnLeave(on_leave) => Self::OnLeave(on_leave.into()),
57        }
58    }
59}
60
61impl From<proto::OnJoin> for OnJoinEvent {
62    fn from(_: proto::OnJoin) -> Self {
63        Self {}
64    }
65}
66
67impl From<OnJoinEvent> for proto::OnJoin {
68    fn from(_: OnJoinEvent) -> Self {
69        Self {}
70    }
71}
72
73impl From<proto::OnLeave> for OnLeaveEvent {
74    fn from(ev: proto::OnLeave) -> Self {
75        Self {
76            reason: proto::on_leave::Reason::try_from(ev.reason)
77                .unwrap_or_default()
78                .into(),
79        }
80    }
81}
82
83impl From<OnLeaveEvent> for proto::OnLeave {
84    fn from(ev: OnLeaveEvent) -> Self {
85        Self { reason: proto::on_leave::Reason::from(ev.reason).into() }
86    }
87}
88
89impl From<proto::on_leave::Reason> for OnLeaveReason {
90    fn from(rsn: proto::on_leave::Reason) -> Self {
91        use proto::on_leave::Reason;
92
93        match rsn {
94            Reason::Lost => Self::Lost,
95            Reason::Shutdown => Self::Shutdown,
96            Reason::Disconnected => Self::Disconnected,
97            Reason::Kicked => Self::Kicked,
98        }
99    }
100}
101
102impl From<OnLeaveReason> for proto::on_leave::Reason {
103    fn from(rsn: OnLeaveReason) -> Self {
104        match rsn {
105            OnLeaveReason::Lost => Self::Lost,
106            OnLeaveReason::Shutdown => Self::Shutdown,
107            OnLeaveReason::Disconnected => Self::Disconnected,
108            OnLeaveReason::Kicked => Self::Kicked,
109        }
110    }
111}