hydro_lang/networking/
mod.rs1use std::marker::PhantomData;
4
5use serde::Serialize;
6use serde::de::DeserializeOwned;
7
8use crate::live_collections::stream::networking::{deserialize_bincode, serialize_bincode};
9use crate::nondet::NonDet;
10
11#[sealed::sealed]
12trait SerKind<T: ?Sized> {
13 fn serialize_thunk(is_demux: bool) -> syn::Expr;
14
15 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr;
16}
17
18pub enum Bincode {}
20
21#[sealed::sealed]
22impl<T: Serialize + DeserializeOwned> SerKind<T> for Bincode {
23 fn serialize_thunk(is_demux: bool) -> syn::Expr {
24 serialize_bincode::<T>(is_demux)
25 }
26
27 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr {
28 deserialize_bincode::<T>(tagged)
29 }
30}
31
32pub enum NoSer {}
34
35#[sealed::sealed]
36trait TransportKind {
37 fn networking_info() -> NetworkingInfo;
39}
40
41#[sealed::sealed]
42#[diagnostic::on_unimplemented(
43 message = "TCP transport requires a failure policy. For example, `TCP.fail_stop()` stops sending messages after a failed connection."
44)]
45trait TcpFailPolicy {
46 fn tcp_fault() -> TcpFault;
48}
49
50pub enum FailStop {}
52#[sealed::sealed]
53impl TcpFailPolicy for FailStop {
54 fn tcp_fault() -> TcpFault {
55 TcpFault::FailStop
56 }
57}
58
59pub enum Lossy {}
61#[sealed::sealed]
62impl TcpFailPolicy for Lossy {
63 fn tcp_fault() -> TcpFault {
64 TcpFault::Lossy
65 }
66}
67
68pub struct Tcp<F> {
70 _phantom: PhantomData<F>,
71}
72
73#[sealed::sealed]
74impl<F: TcpFailPolicy> TransportKind for Tcp<F> {
75 fn networking_info() -> NetworkingInfo {
76 NetworkingInfo::Tcp {
77 fault: F::tcp_fault(),
78 }
79 }
80}
81
82#[sealed::sealed]
84pub trait NetworkFor<T: ?Sized> {
85 fn serialize_thunk(is_demux: bool) -> syn::Expr;
87
88 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr;
90
91 fn name(&self) -> Option<&str>;
93
94 fn networking_info() -> NetworkingInfo;
96}
97
98#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
100pub enum TcpFault {
101 FailStop,
103 Lossy,
105}
106
107#[derive(Debug, Clone, PartialEq, Eq, Hash)]
109pub enum NetworkingInfo {
110 Tcp {
112 fault: TcpFault,
114 },
115}
116
117pub struct NetworkingConfig<Tr: ?Sized, S: ?Sized, Name = ()> {
120 name: Option<Name>,
121 _phantom: (PhantomData<Tr>, PhantomData<S>),
122}
123
124impl<Tr: ?Sized, S: ?Sized> NetworkingConfig<Tr, S> {
125 pub fn name(self, name: impl Into<String>) -> NetworkingConfig<Tr, S, String> {
127 NetworkingConfig {
128 name: Some(name.into()),
129 _phantom: (PhantomData, PhantomData),
130 }
131 }
132}
133
134impl<Tr: ?Sized, N> NetworkingConfig<Tr, NoSer, N> {
135 pub const fn bincode(mut self) -> NetworkingConfig<Tr, Bincode, N> {
137 let taken_name = self.name.take();
138 std::mem::forget(self); NetworkingConfig {
140 name: taken_name,
141 _phantom: (PhantomData, PhantomData),
142 }
143 }
144}
145
146impl<S: ?Sized> NetworkingConfig<Tcp<()>, S> {
147 pub const fn fail_stop(self) -> NetworkingConfig<Tcp<FailStop>, S> {
155 NetworkingConfig {
156 name: self.name,
157 _phantom: (PhantomData, PhantomData),
158 }
159 }
160
161 pub const fn lossy(self, nondet: NonDet) -> NetworkingConfig<Tcp<Lossy>, S> {
170 let _ = nondet;
171 NetworkingConfig {
172 name: self.name,
173 _phantom: (PhantomData, PhantomData),
174 }
175 }
176}
177
178#[sealed::sealed]
179impl<Tr: ?Sized, S: ?Sized, T: ?Sized> NetworkFor<T> for NetworkingConfig<Tr, S>
180where
181 Tr: TransportKind,
182 S: SerKind<T>,
183{
184 fn serialize_thunk(is_demux: bool) -> syn::Expr {
185 S::serialize_thunk(is_demux)
186 }
187
188 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr {
189 S::deserialize_thunk(tagged)
190 }
191
192 fn name(&self) -> Option<&str> {
193 None
194 }
195
196 fn networking_info() -> NetworkingInfo {
197 Tr::networking_info()
198 }
199}
200
201#[sealed::sealed]
202impl<Tr: ?Sized, S: ?Sized, T: ?Sized> NetworkFor<T> for NetworkingConfig<Tr, S, String>
203where
204 Tr: TransportKind,
205 S: SerKind<T>,
206{
207 fn serialize_thunk(is_demux: bool) -> syn::Expr {
208 S::serialize_thunk(is_demux)
209 }
210
211 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr {
212 S::deserialize_thunk(tagged)
213 }
214
215 fn name(&self) -> Option<&str> {
216 self.name.as_deref()
217 }
218
219 fn networking_info() -> NetworkingInfo {
220 Tr::networking_info()
221 }
222}
223
224pub const TCP: NetworkingConfig<Tcp<()>, NoSer> = NetworkingConfig {
226 name: None,
227 _phantom: (PhantomData, PhantomData),
228};