mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-25 12:00:35 +00:00
tokio-io: Add unsplit
. (#807)
Provide a way to restore an I/O object from its `ReadHalf` and `WriteHalf`. Closes #803 Co-Authored-By: twittner <tw@dtex.org>
This commit is contained in:
parent
02a5091885
commit
fd22090df8
@ -143,6 +143,9 @@ pub trait AsyncRead: std_io::Read {
|
||||
///
|
||||
/// The two halves returned implement the `Read` and `Write` traits,
|
||||
/// respectively.
|
||||
///
|
||||
/// To restore this read/write object from its `ReadHalf` and `WriteHalf`
|
||||
/// use `unsplit`.
|
||||
fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
|
||||
where
|
||||
Self: AsyncWrite + Sized,
|
||||
|
@ -12,12 +12,44 @@ pub struct ReadHalf<T> {
|
||||
handle: BiLock<T>,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> ReadHalf<T> {
|
||||
/// Reunite with a previously split `WriteHalf`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If this `ReadHalf` and the given `WriteHalf` do not originate from
|
||||
/// the same `AsyncRead::split` operation this method will panic.
|
||||
pub fn unsplit(self, w: WriteHalf<T>) -> T {
|
||||
if let Ok(x) = self.handle.reunite(w.handle) {
|
||||
x
|
||||
} else {
|
||||
panic!("Unrelated `WriteHalf` passed to `ReadHalf::unsplit`.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The writable half of an object returned from `AsyncRead::split`.
|
||||
#[derive(Debug)]
|
||||
pub struct WriteHalf<T> {
|
||||
handle: BiLock<T>,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> WriteHalf<T> {
|
||||
/// Reunite with a previously split `ReadHalf`.
|
||||
///
|
||||
/// # panics
|
||||
///
|
||||
/// If this `WriteHalf` and the given `ReadHalf` do not originate from
|
||||
/// the same `AsyncRead::split` operation this method will panic.
|
||||
pub fn unsplit(self, r: ReadHalf<T>) -> T {
|
||||
if let Ok(x) = self.handle.reunite(r.handle) {
|
||||
x
|
||||
} else {
|
||||
panic!("Unrelated `ReadHalf` passed to `WriteHalf::unsplit`.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split<T: AsyncRead + AsyncWrite>(t: T) -> (ReadHalf<T>, WriteHalf<T>) {
|
||||
let (a, b) = BiLock::new(t);
|
||||
(ReadHalf { handle: a }, WriteHalf { handle: b })
|
||||
@ -171,4 +203,45 @@ mod tests {
|
||||
}))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsplit_ok() {
|
||||
let (r, w) = RW.split();
|
||||
r.unsplit(w);
|
||||
|
||||
let (r, w) = RW.split();
|
||||
w.unsplit(r);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn unsplit_err1() {
|
||||
let (r, _) = RW.split();
|
||||
let (_, w) = RW.split();
|
||||
r.unsplit(w);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn unsplit_err2() {
|
||||
let (_, w) = RW.split();
|
||||
let (r, _) = RW.split();
|
||||
r.unsplit(w);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn unsplit_err3() {
|
||||
let (_, w) = RW.split();
|
||||
let (r, _) = RW.split();
|
||||
w.unsplit(r);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn unsplit_err4() {
|
||||
let (r, _) = RW.split();
|
||||
let (_, w) = RW.split();
|
||||
w.unsplit(r);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user