reach_core/communication/
mod.rs1#[cfg(feature = "websocket")]
6use rand_core::CryptoRngCore;
7
8use reach_aliases::*;
9
10#[cfg(feature = "websocket")]
11use crate::RandomFromRng;
12use crate::error;
13
14mod proto {
15 include!(concat!(env!("OUT_DIR"), "/reach.communication.rs"));
16}
17
18#[cfg(all(feature = "reachable", feature = "websocket"))]
19pub mod secrets;
20
21mod traits;
22pub use traits::*;
23
24#[derive(Debug, Clone, Eq, PartialEq)]
25pub struct Communication<T> {
26 pub r#type: T,
27 pub inner: Vec<u8>,
28 pub augmentation: Option<Vec<u8>>,
29}
30
31impl<T> Communication<T>
32where
33 T: CommunicableType,
34{
35 pub fn new(r#type: T) -> Self {
36 Self::from(r#type, vec![], None)
37 }
38
39 #[cfg(feature = "websocket")]
40 pub fn tag(self, csprng: &mut impl CryptoRngCore) -> (Self, Vec<u8>) {
41 let tag = OneSix::random_from_rng(csprng).to_vec();
42 (
43 Self {
44 r#type: self.r#type,
45 inner: self.inner,
46 augmentation: Some(tag.clone()),
47 },
48 tag,
49 )
50 }
51
52 #[cfg(feature = "reachable")]
53 pub fn with_tag(mut self, tag: Vec<u8>) -> Self {
54 self.augmentation.replace(tag);
55 self
56 }
57
58 pub fn with_augmentation(mut self, augmentation: Option<Vec<u8>>) -> Self {
59 self.augmentation = augmentation;
60 self
61 }
62
63 pub fn pad_to(self, length: usize) -> Self {
64 let padding = length.saturating_sub(self.inner.len() + 1);
65
66 Self {
67 r#type: self.r#type,
68 inner: self.inner,
69 augmentation: Some(vec![0; padding]),
70 }
71 }
72
73 pub fn from(r#type: T, inner: Vec<u8>, augmentation: Option<Vec<u8>>) -> Self {
74 Self {
75 r#type,
76 inner,
77 augmentation,
78 }
79 }
80
81 pub fn encode(self) -> Vec<u8> {
82 proto::Communication::from(self).encode_to_vec()
83 }
84
85 pub fn decode(bytes: impl AsRef<[u8]>) -> Result<Self, error::DecodeError> {
86 Self::try_from(proto::Communication::decode(bytes.as_ref())?)
87 }
88}
89
90impl<T> TryFrom<proto::Communication> for Communication<T>
91where
92 T: CommunicableType,
93{
94 type Error = error::DecodeError;
95
96 fn try_from(value: proto::Communication) -> Result<Self, Self::Error> {
97 Ok(Self::from(
98 T::try_from(value.r#type).map_err(|_| error::DecodeError)?,
99 value.inner,
100 value.augmentation,
101 ))
102 }
103}
104
105impl<T> From<Communication<T>> for proto::Communication
106where
107 T: CommunicableType,
108{
109 fn from(value: Communication<T>) -> Self {
110 proto::Communication {
111 r#type: value.r#type.into(),
112 inner: value.inner,
113 augmentation: value.augmentation,
114 }
115 }
116}
117
118pub struct LocalCommunication {}
119pub struct RemoteCommunication {}