reach_core/communication/
traits.rs

1// SPDX-FileCopyrightText: 2024-2025 eaon <eaon@posteo.net>
2// SPDX-FileCopyrightText: 2025 Michael Goldenberg <m@mgoldenberg.net>
3// SPDX-License-Identifier: EUPL-1.2
4
5use super::*;
6use crate::{ProstDecode, ProstEncode, ProstEncodeOwned};
7
8pub trait CommunicableType: TryFrom<i32> + Into<i32> {}
9
10pub trait CommunicableTypes {
11    type Req: CommunicableType;
12    type Resp: CommunicableType;
13    type Variant;
14}
15
16pub trait Communicable<T>: Sized
17where
18    T: CommunicableType,
19{
20    fn to_communication(&self) -> Communication<T>;
21
22    fn try_from_communication(communication: &Communication<T>)
23    -> Result<Self, error::DecodeError>;
24}
25
26pub trait MatchResponse<Req> {
27    type Resp;
28}
29
30pub trait ErrorSubset: From<Self::Error> {
31    type Error;
32}
33
34pub trait ProstCommunicable<T>
35where
36    T: CommunicableType + PartialEq,
37    Self: ProstEncode + ProstDecode,
38{
39    const COMMUNICATION_VARIANT: T;
40
41    fn to_communication_via_prost(&self) -> Communication<T> {
42        Communication::from(Self::COMMUNICATION_VARIANT, self.encode_to_vec(), None)
43    }
44
45    fn try_from_communication(
46        communication: &Communication<T>,
47    ) -> Result<Self, error::DecodeError> {
48        if communication.r#type != Self::COMMUNICATION_VARIANT {
49            return Err(error::DecodeError);
50        }
51
52        Self::decode(&communication.inner)
53    }
54}
55
56impl<T, C> Communicable<T> for C
57where
58    T: CommunicableType + PartialEq,
59    C: ProstCommunicable<T>,
60{
61    fn to_communication(&self) -> Communication<T> {
62        C::to_communication_via_prost(self)
63    }
64
65    fn try_from_communication(
66        communication: &Communication<T>,
67    ) -> Result<Self, error::DecodeError> {
68        C::try_from_communication(communication)
69    }
70}
71
72pub trait CommunicableOwned<T>: Sized
73where
74    T: CommunicableType,
75{
76    fn to_communication(self) -> Communication<T>;
77
78    fn try_from_communication(communication: &Communication<T>)
79    -> Result<Self, error::DecodeError>;
80}
81
82pub trait ProstCommunicableOwned<T>
83where
84    T: CommunicableType,
85    Self: ProstEncodeOwned + ProstDecode + Sized,
86{
87    const COMMUNICATION_VARIANT: T;
88
89    fn to_communication_via_prost(self) -> Communication<T> {
90        Communication::from(Self::COMMUNICATION_VARIANT, self.encode_to_vec(), None)
91    }
92
93    fn try_from_communication(
94        communication: &Communication<T>,
95    ) -> Result<Self, error::DecodeError> {
96        Self::decode(&communication.inner)
97    }
98}
99
100impl<T, C> CommunicableOwned<T> for C
101where
102    T: CommunicableType,
103    C: ProstCommunicableOwned<T>,
104{
105    fn to_communication(self) -> Communication<T> {
106        C::to_communication_via_prost(self)
107    }
108
109    fn try_from_communication(
110        communication: &Communication<T>,
111    ) -> Result<Self, error::DecodeError> {
112        C::try_from_communication(communication)
113    }
114}
115
116pub trait IntoAugmentation {
117    fn into_augmentation(self) -> Option<Vec<u8>>;
118}
119
120impl IntoAugmentation for () {
121    fn into_augmentation(self) -> Option<Vec<u8>> {
122        None
123    }
124}
125
126impl IntoAugmentation for Vec<u8> {
127    fn into_augmentation(self) -> Option<Vec<u8>> {
128        Some(self)
129    }
130}