From 6cd1d7f93bd6f150341582a1b54087cefffdbf87 Mon Sep 17 00:00:00 2001
From: "Eli W. Hunter" <42009212+elihunter173@users.noreply.github.com>
Date: Thu, 23 Jul 2020 23:54:12 -0400
Subject: Async/Await Support (continuation of #191) (#229)
* it builds!
* remove unused dependencies
* bump dependencies
* reimplement 'exec' endpoint
* update a few more examples
* update remaining examples
* fix doc tests, remove unused 'read' module
* remove feature-gated async closures
* split futures dependency to just 'futures-util'
* update version and readme
* make functions accepting Body generic over Into
again
* update changelog
* reinstate 'unix-socket' feature
* reinstate 'attach' endpoint
* fix clippy lints
* fix documentation typo
* fix container copyfrom/into implementations
* add convenience methods for TtyChunk struct
* remove 'main' from code example to silence clippy lint
* Update hyper to 0.13.1
* Add Send bounds to TtyWriter
* Appease clippy
* Fix examples
* Update issue in changelog
Co-authored-by: Daniel Eades
Co-authored-by: Marc Schreiber
---
src/tty.rs | 372 ++++++++++++++++++++++---------------------------------------
1 file changed, 133 insertions(+), 239 deletions(-)
(limited to 'src/tty.rs')
diff --git a/src/tty.rs b/src/tty.rs
index a4ab27f..a26846f 100644
--- a/src/tty.rs
+++ b/src/tty.rs
@@ -1,278 +1,172 @@
-use crate::errors::Error;
-use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
-use bytes::BytesMut;
-use futures::{self, Async};
-use hyper::rt::{Future, Stream};
-use log::trace;
-use std::io::{self, Cursor};
-use tokio_codec::Decoder;
-use tokio_io::{AsyncRead, AsyncWrite};
-
-#[derive(Debug)]
-pub struct Chunk {
- pub stream_type: StreamType,
- pub data: Vec,
-}
-
-#[derive(Debug, Clone, Copy)]
-pub enum StreamType {
- StdIn,
- StdOut,
- StdErr,
-}
-
-/// A multiplexed stream.
-pub struct Multiplexed {
- stdin: Box,
- chunks: Box>,
-}
-
-pub struct MultiplexedBlocking {
- stdin: Box,
- chunks: Box>>,
-}
-
-/// Represent the current state of the decoding of a TTY frame
-enum TtyDecoderState {
- /// We have yet to read a frame header
- WaitingHeader,
- /// We have read a header and extracted the payload size and stream type,
- /// and are now waiting to read the corresponding payload
- WaitingPayload(usize, StreamType),
-}
-
-pub struct TtyDecoder {
- state: TtyDecoderState,
-}
-
-impl Chunk {
- /// Interprets the raw bytes as a string.
- ///
- /// Returns `None` if the raw bytes do not represent
- /// a valid UTF-8 string.
- pub fn as_string(&self) -> Option {
- String::from_utf8(self.data.clone()).ok()
- }
-
- /// Unconditionally interprets the raw bytes as a string.
- ///
- /// Inserts placeholder symbols for all non-character bytes.
- pub fn as_string_lossy(&self) -> String {
- String::from_utf8_lossy(&self.data).into_owned()
+//! Types for working with docker TTY streams
+
+use crate::{Error, Result};
+use bytes::{BigEndian, ByteOrder};
+use futures_util::{
+ io::{AsyncRead, AsyncReadExt, AsyncWrite},
+ stream::{Stream, TryStreamExt},
+};
+use pin_project::pin_project;
+use std::io;
+
+/// An enum representing a chunk of TTY text streamed from a Docker container.
+///
+/// For convenience, this type can deref to the contained `Vec`.
+#[derive(Debug, Clone)]
+pub enum TtyChunk {
+ StdIn(Vec),
+ StdOut(Vec),
+ StdErr(Vec),
+}
+
+impl From for Vec {
+ fn from(tty_chunk: TtyChunk) -> Self {
+ match tty_chunk {
+ TtyChunk::StdIn(bytes) | TtyChunk::StdOut(bytes) | TtyChunk::StdErr(bytes) => bytes,
+ }
}
}
-impl TtyDecoder {
- pub fn new() -> Self {
- Self {
- state: TtyDecoderState::WaitingHeader,
+impl AsRef> for TtyChunk {
+ fn as_ref(&self) -> &Vec {
+ match self {
+ TtyChunk::StdIn(bytes) | TtyChunk::StdOut(bytes) | TtyChunk::StdErr(bytes) => bytes,
}
}
}
-impl Default for TtyDecoder {
- fn default() -> Self {
- Self::new()
+impl std::ops::Deref for TtyChunk {
+ type Target = Vec;
+ fn deref(&self) -> &Self::Target {
+ self.as_ref()
}
}
-impl Decoder for TtyDecoder {
- type Item = Chunk;
- type Error = Error;
-
- fn decode(
- &mut self,
- src: &mut BytesMut,
- ) -> Result