Skip to content

Commit 0797b72

Browse files
initial commit
0 parents  commit 0797b72

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock

Cargo.toml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "protocol-serde"
3+
version = "0.1.0"
4+
authors = ["Izzy Swart <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
protocol = { git = "https://github.com/noocene/protocol" }
9+
serde = { version = "1.0.104", default-features = false }
10+
futures = { version = "0.3.1", default-features = false }
11+
12+
[features]
13+
alloc = ["serde/alloc"]
14+
std = []
15+
default = ["std", "alloc"]

src/lib.rs

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#![cfg_attr(not(feature = "std"), no_std)]
2+
3+
#[cfg(feature = "alloc")]
4+
extern crate alloc;
5+
6+
use core::{
7+
num::{
8+
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
9+
NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
10+
},
11+
sync::atomic::{
12+
AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32,
13+
AtomicU64, AtomicU8, AtomicUsize,
14+
},
15+
time::Duration,
16+
};
17+
use futures::{
18+
future::{ready, Map, Ready},
19+
stream::{once, Forward, Once, StreamFuture},
20+
FutureExt, Sink, StreamExt,
21+
};
22+
use protocol::{Bottom, Channels, Format, Protocol};
23+
use serde::{de::DeserializeOwned, Serialize};
24+
25+
#[macro_export]
26+
macro_rules! Serde {
27+
($item:item) => {
28+
#[derive(::serde::Serialize, ::serde::Deserialize)]
29+
$item
30+
};
31+
}
32+
33+
#[derive(Debug)]
34+
pub struct Insufficient;
35+
36+
pub trait Serializer {
37+
type SerializeError;
38+
type DeserializeError;
39+
type Representation;
40+
41+
fn serialize<T: Serialize + DeserializeOwned>(
42+
&mut self,
43+
item: T,
44+
) -> Result<Self::Representation, Self::SerializeError>;
45+
46+
fn deserialize<T: Serialize + DeserializeOwned>(
47+
&mut self,
48+
item: Self::Representation,
49+
) -> Result<T, Self::DeserializeError>;
50+
}
51+
52+
pub struct Serde<T: Serializer>(T);
53+
54+
impl<T: Serializer, U: Serialize + DeserializeOwned> Format<U> for Serde<T> {
55+
type Representation = T::Representation;
56+
type SerializeError = T::SerializeError;
57+
type Serialize = Ready<Result<T::Representation, T::SerializeError>>;
58+
type DeserializeError = T::DeserializeError;
59+
type Deserialize = Ready<Result<U, T::DeserializeError>>;
60+
61+
fn serialize(&mut self, item: U) -> Self::Serialize {
62+
ready(self.0.serialize(item))
63+
}
64+
65+
fn deserialize(&mut self, item: T::Representation) -> Self::Deserialize {
66+
ready(self.0.deserialize(item))
67+
}
68+
}
69+
70+
// impl<T: Serializer> Format<Bottom> for Serde<T> {
71+
// type Representation = T::Representation;
72+
// type SerializeError = T::SerializeError;
73+
// type Serialize = Ready<Result<T::Representation, T::SerializeError>>;
74+
// type DeserializeError = T::DeserializeError;
75+
// type Deserialize = Ready<Result<Bottom, T::DeserializeError>>;
76+
77+
// fn serialize(&mut self, _: Bottom) -> Self::Serialize {
78+
// panic!("attempted to serialize bottom type")
79+
// }
80+
81+
// fn deserialize(&mut self, _: T::Representation) -> Self::Deserialize {
82+
// panic!("attempted to deserialize bottom type")
83+
// }
84+
// }
85+
86+
macro_rules! flat {
87+
( $( $x:ty ),* ) => {
88+
$(
89+
impl<T: Serializer, C: Channels<$x, Bottom>> Protocol<Serde<T>, C> for $x
90+
where
91+
C::Unravel: Unpin,
92+
C::Coalesce: Unpin
93+
{
94+
type Unravel = $x;
95+
type UnravelError = <C::Unravel as Sink<$x>>::Error;
96+
type UnravelFuture =
97+
Forward<Once<Ready<Result<$x, <C::Unravel as Sink<$x>>::Error>>>, C::Unravel>;
98+
type Coalesce = Bottom;
99+
type CoalesceError = Insufficient;
100+
type CoalesceFuture =
101+
Map<StreamFuture<C::Coalesce>, fn((Option<$x>, C::Coalesce)) -> Result<$x, Insufficient>>;
102+
103+
fn unravel(self, channel: C::Unravel) -> Self::UnravelFuture {
104+
once(ready(Ok(self))).forward(channel)
105+
}
106+
107+
fn coalesce(channel: C::Coalesce) -> Self::CoalesceFuture {
108+
fn map<St>(next: (Option<$x>, St)) -> Result<$x, Insufficient> {
109+
next.0.ok_or(Insufficient)
110+
}
111+
channel.into_future().map(map::<C::Coalesce>)
112+
}
113+
}
114+
)*
115+
};
116+
( #[doc = $doc:literal] $( $x:ty ),* ) => {
117+
$(
118+
#[doc = $doc]
119+
flat!($x);
120+
)*
121+
};
122+
}
123+
124+
flat! {
125+
bool, char, f32, f64, Duration,
126+
usize, u8, u16, u32, u64, u128,
127+
isize, i8, i16, i32, i64, i128,
128+
AtomicBool,
129+
AtomicIsize, AtomicI8, AtomicI16, AtomicI32, AtomicI64,
130+
AtomicUsize, AtomicU8, AtomicU16, AtomicU32, AtomicU64,
131+
NonZeroIsize, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128,
132+
NonZeroUsize, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128
133+
}
134+
135+
#[cfg(feature = "std")]
136+
mod std {
137+
use super::*;
138+
use ::std::{
139+
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
140+
time::SystemTime,
141+
};
142+
flat! {
143+
/// *This requires the `alloc` feature, which is enabled by default*
144+
IpAddr, Ipv4Addr, Ipv6Addr,
145+
SocketAddr, SocketAddrV4, SocketAddrV6,
146+
SystemTime
147+
}
148+
}
149+
150+
#[cfg(feature = "alloc")]
151+
mod _alloc {
152+
use super::*;
153+
use ::alloc::string::String;
154+
flat! {
155+
// *This requires the `alloc` feature, which is enabled by default*
156+
String
157+
}
158+
}

0 commit comments

Comments
 (0)