Skip to content

Commit

Permalink
[Enhancement] Write to std::io::Writers (#78)
Browse files Browse the repository at this point in the history
* Added ::= Writer

* Added ::= Writer::write_silently

* Added ::= Writer::write_loudly

* Added ::= tests for ``Writer``

* Create summary of recent changes

* Update 20240128_160529_GitHub_Actions_writer.ron

---------

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
kevinmatthes and github-actions[bot] committed Jan 28, 2024
1 parent 2d379bc commit fe04daa
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 1 deletion.
11 changes: 11 additions & 0 deletions changelog.d/20240128_160529_GitHub_Actions_writer.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(
references: {},
changes: {
"Added": [
"Writer",
"Writer::write_loudly",
"Writer::write_silently",
"tests for Writer",
],
},
)
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ mod reading;
mod writing;

pub use reading::{BufReadReader, OptionReader, PathBufLikeReader};
pub use writing::PathBufLikeTruncation;
pub use writing::{PathBufLikeTruncation, Writer};

/// This crate's name.
pub const NAME: &str = "aeruginous-io";
Expand Down
68 changes: 68 additions & 0 deletions src/writing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,72 @@ where
}
}

/// Write to a [`std::io::Write`]r.
pub trait Writer<T>
where
T: std::io::Write,
{
/// Write the data this method is called on to the given destination.
///
/// This method behaves just like [`crate::Writer::write_silently`] despite
/// also printing error messages to [`std::io::Stderr`].
///
/// # Errors
///
/// See [`sysexits::ExitCode`].
fn write_loudly(self, destination: T) -> Result<()>;

/// Write the data this method is called on to the given destination.
///
/// The data this method is called on will be converted to a [`String`] and
/// written to the given destination. The data therefore needs to implement
/// [`ToString`]. The destination needs to implement [`std::io::Write`].
///
/// The return value is either the unit type, in case of success, or a
/// [`sysexits::ExitCode`] to describe the error cause, otherwise.
///
/// Error messages are not written to [`std::io::Stderr`].
///
/// # Errors
///
/// See [`sysexits::ExitCode`].
fn write_silently(self, destination: T) -> Result<()>;
}

impl<T: ToString, W: Write> Writer<W> for T {
fn write_loudly(self, mut destination: W) -> Result<()> {
let bytes = self.to_string().as_bytes().to_vec();

match destination.write(&bytes) {
Err(e) => {
eprintln!("{e}");
Err(e.into())
}
Ok(n) => {
if n == bytes.len() {
Ok(())
} else {
eprintln!("Creating an exact copy was not possible.");
Err(sysexits::ExitCode::IoErr)
}
}
}
}

fn write_silently(self, mut destination: W) -> Result<()> {
let bytes = self.to_string().as_bytes().to_vec();

match destination.write(&bytes) {
Err(e) => Err(e.into()),
Ok(n) => {
if n == bytes.len() {
Ok(())
} else {
Err(sysexits::ExitCode::IoErr)
}
}
}
}
}

/******************************************************************************/
20 changes: 20 additions & 0 deletions tests/writing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,24 @@ mod path_buf_like_truncation {
}
}

mod writer {
use aeruginous_io::Writer;

#[test]
fn write_loudly_success() {
let mut buffer = Vec::new();

assert!("test".write_loudly(&mut buffer).is_ok());
assert_eq!(buffer, b"test");
}

#[test]
fn write_silently_success() {
let mut buffer = Vec::new();

assert!("test".write_silently(&mut buffer).is_ok());
assert_eq!(buffer, b"test");
}
}

/******************************************************************************/

0 comments on commit fe04daa

Please sign in to comment.