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};
9
10#[sealed::sealed]
11trait SerKind<T: ?Sized> {
12 fn serialize_thunk(is_demux: bool) -> syn::Expr;
13
14 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr;
15}
16
17pub enum Bincode {}
19
20#[sealed::sealed]
21impl<T: Serialize + DeserializeOwned> SerKind<T> for Bincode {
22 fn serialize_thunk(is_demux: bool) -> syn::Expr {
23 serialize_bincode::<T>(is_demux)
24 }
25
26 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr {
27 deserialize_bincode::<T>(tagged)
28 }
29}
30
31pub enum NoSer {}
33
34#[sealed::sealed]
35trait TransportKind {}
36
37#[sealed::sealed]
38#[diagnostic::on_unimplemented(
39 message = "TCP transport requires a failure policy. For example, `TCP.fail_stop()` stops sending messages after a failed connection."
40)]
41trait TcpFailPolicy {}
42
43pub enum FailStop {}
45#[sealed::sealed]
46impl TcpFailPolicy for FailStop {}
47
48pub struct Tcp<F> {
50 _phantom: PhantomData<F>,
51}
52
53#[sealed::sealed]
54impl<F: TcpFailPolicy> TransportKind for Tcp<F> {}
55
56#[sealed::sealed]
58pub trait NetworkFor<T: ?Sized> {
59 fn serialize_thunk(is_demux: bool) -> syn::Expr;
61
62 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr;
64
65 fn name(&self) -> Option<&str>;
67}
68
69pub struct NetworkingConfig<Tr: ?Sized, S: ?Sized, Name = ()> {
72 name: Option<Name>,
73 _phantom: (PhantomData<Tr>, PhantomData<S>),
74}
75
76impl<Tr: ?Sized, S: ?Sized> NetworkingConfig<Tr, S> {
77 pub const fn bincode(self) -> NetworkingConfig<Tr, Bincode> {
79 NetworkingConfig {
80 name: self.name,
81 _phantom: (PhantomData, PhantomData),
82 }
83 }
84
85 pub fn name(self, name: impl Into<String>) -> NetworkingConfig<Tr, S, String> {
87 NetworkingConfig {
88 name: Some(name.into()),
89 _phantom: (PhantomData, PhantomData),
90 }
91 }
92}
93
94impl<S: ?Sized> NetworkingConfig<Tcp<()>, S> {
95 pub const fn fail_stop(self) -> NetworkingConfig<Tcp<FailStop>, S> {
103 NetworkingConfig {
104 name: self.name,
105 _phantom: (PhantomData, PhantomData),
106 }
107 }
108}
109
110#[sealed::sealed]
111impl<Tr: ?Sized, S: ?Sized, T: ?Sized> NetworkFor<T> for NetworkingConfig<Tr, S>
112where
113 Tr: TransportKind,
114 S: SerKind<T>,
115{
116 fn serialize_thunk(is_demux: bool) -> syn::Expr {
117 S::serialize_thunk(is_demux)
118 }
119
120 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr {
121 S::deserialize_thunk(tagged)
122 }
123
124 fn name(&self) -> Option<&str> {
125 None
126 }
127}
128
129#[sealed::sealed]
130impl<Tr: ?Sized, S: ?Sized, T: ?Sized> NetworkFor<T> for NetworkingConfig<Tr, S, String>
131where
132 Tr: TransportKind,
133 S: SerKind<T>,
134{
135 fn serialize_thunk(is_demux: bool) -> syn::Expr {
136 S::serialize_thunk(is_demux)
137 }
138
139 fn deserialize_thunk(tagged: Option<&syn::Type>) -> syn::Expr {
140 S::deserialize_thunk(tagged)
141 }
142
143 fn name(&self) -> Option<&str> {
144 self.name.as_deref()
145 }
146}
147
148pub const TCP: NetworkingConfig<Tcp<()>, NoSer> = NetworkingConfig {
150 name: None,
151 _phantom: (PhantomData, PhantomData),
152};