1use std::marker::PhantomData;
7
8use compio_buf::IoBufMut;
9use futures_util::FutureExt;
10
11use crate::{AsyncRead, framed::codec::Decoder, util::Splittable};
12
13pub mod codec;
14pub mod frame;
15
16mod read;
17mod write;
18
19const CONFIG_POLLED_ERROR: &str = "`Framed` should not be configured after being polled";
20const INCONSISTENT_ERROR: &str = "`Framed` is in an inconsistent state";
21
22#[cold]
23fn panic_config_polled() -> ! {
24 panic!("{}", CONFIG_POLLED_ERROR);
25}
26
27pub struct Framed<R, W, C, F, In, Out, B = Vec<u8>> {
38 read_state: read::State<R, B>,
39 write_state: write::State<W, B>,
40 codec: C,
41 framer: F,
42 types: PhantomData<(In, Out)>,
43}
44
45pub type SymmetricFramed<R, W, C, F, T, B = Vec<u8>> = Framed<R, W, C, F, T, T, B>;
50
51impl<R, W, C, F, In, Out, B> Framed<R, W, C, F, In, Out, B> {
52 pub fn with_reader<Io>(self, reader: Io) -> Framed<Io, W, C, F, In, Out, B> {
54 Framed {
55 read_state: self.read_state.with_io(reader),
56 write_state: self.write_state,
57 codec: self.codec,
58 framer: self.framer,
59 types: PhantomData,
60 }
61 }
62
63 pub fn with_writer<Io>(self, writer: Io) -> Framed<R, Io, C, F, In, Out, B> {
65 Framed {
66 read_state: self.read_state,
67 write_state: self.write_state.with_io(writer),
68 codec: self.codec,
69 framer: self.framer,
70 types: PhantomData,
71 }
72 }
73
74 pub fn with_duplex<Io: Splittable>(
88 self,
89 io: Io,
90 ) -> Framed<Io::ReadHalf, Io::WriteHalf, C, F, In, Out, B> {
91 let (read_half, write_half) = io.split();
92
93 Framed {
94 read_state: self.read_state.with_io(read_half),
95 write_state: self.write_state.with_io(write_half),
96 codec: self.codec,
97 framer: self.framer,
98 types: PhantomData,
99 }
100 }
101
102 pub fn with_buffer<Buf: IoBufMut>(
107 self,
108 read_buffer: Buf,
109 write_buffer: Buf,
110 ) -> Framed<R, W, C, F, In, Out, Buf> {
111 Framed {
112 read_state: self.read_state.with_buf(read_buffer),
113 write_state: self.write_state.with_buf(write_buffer),
114 codec: self.codec,
115 framer: self.framer,
116 types: PhantomData,
117 }
118 }
119}
120
121impl<C, F> Framed<(), (), C, F, (), (), ()> {
122 pub fn new<In, Out>(codec: C, framer: F) -> Framed<(), (), C, F, In, Out> {
125 Framed {
126 read_state: read::State::empty(),
127 write_state: write::State::empty(),
128 codec,
129 framer,
130 types: PhantomData,
131 }
132 }
133
134 pub fn symmetric<T>(codec: C, framer: F) -> Framed<(), (), C, F, T, T> {
137 Framed {
138 read_state: read::State::empty(),
139 write_state: write::State::empty(),
140 codec,
141 framer,
142 types: PhantomData,
143 }
144 }
145}