aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-03 19:43:06 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-03 19:43:06 -0500
commit8a98d4fee2172d5ac53e74bcc95cd39aa68492a3 (patch)
tree10fb97bbd275fc1ea6a1e69300e7ba1bc1e35430 /src
parent22b2262bdc097ac6ddbe4c7ce488b1afb4f9127e (diff)
downloadttyrec-8a98d4fee2172d5ac53e74bcc95cd39aa68492a3.tar.gz
ttyrec-8a98d4fee2172d5ac53e74bcc95cd39aa68492a3.zip
remove async stuff, clean up everything else
will reintroduce the async stuff in a future commit
Diffstat (limited to 'src')
-rw-r--r--src/creator.rs20
-rw-r--r--src/error.rs28
-rw-r--r--src/frame.rs3
-rw-r--r--src/lib.rs8
-rw-r--r--src/parser.rs4
-rw-r--r--src/reader.rs56
-rw-r--r--src/writer.rs83
7 files changed, 28 insertions, 174 deletions
diff --git a/src/creator.rs b/src/creator.rs
index fac57bb..f4745cc 100644
--- a/src/creator.rs
+++ b/src/creator.rs
@@ -11,6 +11,7 @@ pub struct Creator {
impl Creator {
/// Creates a new `Creator` instance.
+ #[must_use]
pub fn new() -> Self {
Self::default()
}
@@ -29,15 +30,20 @@ impl Creator {
/// Note that this is not guaranteed to do the correct thing unless the
/// `cur_time` parameters given in each `frame_at` call are
/// non-decreasing.
+ #[allow(clippy::missing_panics_doc)]
pub fn frame_at(
&mut self,
cur_time: std::time::Instant,
data: &[u8],
) -> crate::frame::Frame {
+ // this is triggering incorrectly - the code transformation it
+ // suggests doesn't work due to lifetime issues
+ #[allow(clippy::option_if_let_else)]
let base_time = if let Some(base_time) = &self.base_time {
base_time
} else {
self.base_time = Some(cur_time);
+ // this unwrap is safe because we just set the value to Some
self.base_time.as_ref().unwrap()
};
crate::frame::Frame {
@@ -63,16 +69,14 @@ mod test {
let base_time = std::time::Instant::now();
let zero_frame: Vec<u8> =
- std::convert::TryFrom::try_from(creator.frame_at(base_time, b""))
- .unwrap();
+ TryFrom::try_from(creator.frame_at(base_time, b"")).unwrap();
assert_eq!(zero_frame, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
- let data_frame: Vec<u8> =
- std::convert::TryFrom::try_from(creator.frame_at(
- base_time + std::time::Duration::new(38, 123_456_000),
- b"\x1b[2Jfoobar",
- ))
- .unwrap();
+ let data_frame: Vec<u8> = TryFrom::try_from(creator.frame_at(
+ base_time + std::time::Duration::new(38, 123_456_000),
+ b"\x1b[2Jfoobar",
+ ))
+ .unwrap();
assert_eq!(
data_frame,
vec![
diff --git a/src/error.rs b/src/error.rs
index c106d02..9ca35a8 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,30 +1,24 @@
/// Errors potentially returned by this crate.
-#[derive(Debug, snafu::Snafu)]
-#[snafu(visibility(pub))]
+#[derive(Debug)]
pub enum Error {
- /// eof
- #[snafu(display("eof"))]
- EOF,
-
/// failed to create ttyrec frame: got N bytes of data but ttyrec frames
/// can be at most M bytes
- #[snafu(display("failed to create ttyrec frame: got {} bytes of data, but ttyrec frames can be at most {} bytes", input, u32::max_value()))]
FrameTooBig { input: usize },
/// failed to create ttyrec frame: got N seconds but ttyrec frames can be
/// at most M seconds
- #[snafu(display("failed to create ttyrec frame: got {} seconds, but ttyrecs can be at most {} seconds", input, u32::max_value()))]
FrameTooLong { input: u64 },
+}
- /// failed to read from file
- #[cfg(feature = "async")]
- #[snafu(display("failed to read from file: {}", source))]
- ReadFile { source: tokio::io::Error },
-
- /// failed to write to file
- #[cfg(feature = "async")]
- #[snafu(display("failed to write to file: {}", source))]
- WriteFile { source: tokio::io::Error },
+impl std::fmt::Display for Error {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::FrameTooBig { input } => write!(f, "failed to create ttyrec frame: got {} bytes of data, but ttyrec frames can be at most {} bytes", input, u32::max_value()),
+ Self::FrameTooLong { input } => write!(f, "failed to create ttyrec frame: got {} seconds, but ttyrecs can be at most {} seconds", input, u32::max_value()),
+ }
+ }
}
+impl std::error::Error for Error {}
+
pub type Result<T> = std::result::Result<T, Error>;
diff --git a/src/frame.rs b/src/frame.rs
index c617056..71b3988 100644
--- a/src/frame.rs
+++ b/src/frame.rs
@@ -18,7 +18,7 @@ pub struct Frame {
pub data: Vec<u8>,
}
-impl std::convert::TryFrom<Frame> for Vec<u8> {
+impl TryFrom<Frame> for Vec<u8> {
type Error = crate::error::Error;
fn try_from(frame: Frame) -> crate::error::Result<Self> {
@@ -45,7 +45,6 @@ impl std::convert::TryFrom<Frame> for Vec<u8> {
#[cfg(test)]
mod test {
use super::*;
- use std::convert::TryFrom as _;
#[test]
fn test_basic() {
diff --git a/src/lib.rs b/src/lib.rs
index b0d6296..d774aa3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -24,11 +24,3 @@ mod frame;
pub use frame::Frame;
mod parser;
pub use parser::Parser;
-#[cfg(feature = "async")]
-mod reader;
-#[cfg(feature = "async")]
-pub use reader::Reader;
-#[cfg(feature = "async")]
-mod writer;
-#[cfg(feature = "async")]
-pub use writer::Writer;
diff --git a/src/parser.rs b/src/parser.rs
index 45b900e..126eae3 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -34,6 +34,7 @@ pub struct Parser {
impl Parser {
/// Create a new `Parser`.
+ #[must_use]
pub fn new() -> Self {
Self::default()
}
@@ -48,6 +49,7 @@ impl Parser {
/// If a complete frame is found, the bytes for that frame will be removed
/// from the internal buffer and the frame object will be returned. If a
/// complete frame is not found, this method will return `None`.
+ #[allow(clippy::missing_panics_doc)]
pub fn next_frame(&mut self) -> Option<crate::frame::Frame> {
let header = if let Some(header) = &self.read_state {
header
@@ -56,6 +58,7 @@ impl Parser {
return None;
}
+ // these unwraps are guaranteed safe by the length check above
let secs1 = self.reading.pop_front().unwrap();
let secs2 = self.reading.pop_front().unwrap();
let secs3 = self.reading.pop_front().unwrap();
@@ -106,6 +109,7 @@ impl Parser {
/// each frame timestamp after that should be offset by that same amount.
///
/// Returns `None` if no frames have been read yet.
+ #[must_use]
pub fn offset(&self) -> Option<std::time::Duration> {
self.offset
}
diff --git a/src/reader.rs b/src/reader.rs
deleted file mode 100644
index ff5f7f9..0000000
--- a/src/reader.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use snafu::ResultExt as _;
-
-/// Reads ttyrec frames from a `tokio::io::AsyncRead` instance.
-pub struct Reader<R> {
- reader: R,
- parser: crate::parser::Parser,
- read_buf: [u8; 4096],
- done_reading: bool,
-}
-
-impl<R: tokio::io::AsyncRead> Reader<R> {
- /// Creates a new `Reader` from a `tokio::io::AsyncRead` instance.
- pub fn new(reader: R) -> Self {
- Self {
- reader,
- parser: crate::parser::Parser::new(),
- read_buf: [0; 4096],
- done_reading: false,
- }
- }
-
- /// Polls to see if a new frame can be read.
- ///
- /// Returns `Ok(Async::Ready(Some(frame)))` if a frame is available,
- /// `Ok(Async::Ready(None))` if the underlying reader is done, and
- /// `Ok(Async::NotReady)` if not enough bytes have been read for a full
- /// frame.
- pub fn poll_read(
- &mut self,
- ) -> futures::Poll<Option<crate::frame::Frame>, crate::error::Error> {
- loop {
- if let Some(frame) = self.parser.next_frame() {
- return Ok(futures::Async::Ready(Some(frame)));
- } else if self.done_reading {
- return Ok(futures::Async::Ready(None));
- }
-
- let n = futures::try_ready!(self
- .reader
- .poll_read(&mut self.read_buf)
- .context(crate::error::ReadFile));
- if n > 0 {
- self.parser.add_bytes(&self.read_buf[..n]);
- } else {
- self.done_reading = true;
- }
- }
- }
-
- /// How much the timestamps in this file should be offset by.
- ///
- /// See `Parser::offset`.
- pub fn offset(&self) -> Option<std::time::Duration> {
- self.parser.offset()
- }
-}
diff --git a/src/writer.rs b/src/writer.rs
deleted file mode 100644
index 8f79737..0000000
--- a/src/writer.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-use snafu::ResultExt as _;
-
-/// Writes ttyrec frames to a `tokio::io::AsyncWrite` instance.
-pub struct Writer<W> {
- writer: W,
- creator: crate::creator::Creator,
- to_write: std::collections::VecDeque<u8>,
-}
-
-impl<W: tokio::io::AsyncWrite> Writer<W> {
- /// Creates a new `Writer` from a `tokio::io::AsyncWrite` instance.
- pub fn new(writer: W) -> Self {
- Self {
- writer,
- creator: crate::creator::Creator::new(),
- to_write: std::collections::VecDeque::new(),
- }
- }
-
- /// Generates a new ttyrec frame with the given data.
- ///
- /// Equivalent to calling `frame_at` and passing
- /// `std::time::Instant::now()` as the `time` parameter.
- pub fn frame(&mut self, data: &[u8]) -> crate::error::Result<()> {
- self.frame_at(std::time::Instant::now(), data)
- }
-
- /// Generates a new ttyrec frame with the given data at the given time.
- ///
- /// The frame data will be stored on this object until written out by
- /// calls to `poll_write`.
- ///
- /// Note that this is not guaranteed to do the correct thing unless the
- /// `cur_time` parameters given in each `frame_at` call are
- /// non-decreasing.
- pub fn frame_at(
- &mut self,
- time: std::time::Instant,
- data: &[u8],
- ) -> crate::error::Result<()> {
- let frame = self.creator.frame_at(time, data);
- let bytes: Vec<u8> = std::convert::TryFrom::try_from(frame)?;
- self.to_write.extend(bytes.iter());
- Ok(())
- }
-
- /// Attempt to write serialized ttyrec frames to the underlying writer.
- ///
- /// Writes data from the previous calls to `frame` and `frame_at`. Returns
- /// `Ok(Async::Ready(()))` if all bytes were written, and
- /// `Ok(Async::NotReady)` otherwise.
- pub fn poll_write(&mut self) -> futures::Poll<(), crate::error::Error> {
- loop {
- if self.to_write.is_empty() {
- return Ok(futures::Async::Ready(()));
- }
-
- let (a, b) = self.to_write.as_slices();
- let buf = if a.is_empty() { b } else { a };
-
- let n = futures::try_ready!(self
- .writer
- .poll_write(buf)
- .context(crate::error::WriteFile));
-
- if n > 0 {
- for _ in 0..n {
- self.to_write.pop_front();
- }
- } else {
- return Err(crate::error::Error::EOF);
- }
- }
- }
-
- /// Returns `true` if there are still bytes that need to be written.
- ///
- /// It is only necessary to call `poll_write` if this method returns
- /// `true`.
- pub fn needs_write(&self) -> bool {
- !self.to_write.is_empty()
- }
-}