Skip to content

Commit

Permalink
refactor(fmt): Pull out target mod
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Jan 18, 2024
1 parent 8018168 commit f4808e4
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 95 deletions.
98 changes: 3 additions & 95 deletions src/fmt/writer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,108 +1,16 @@
mod atty;
mod buffer;
mod target;

use self::atty::{is_stderr, is_stdout};
use self::buffer::BufferWriter;
use std::{fmt, io, mem, sync::Mutex};

pub(super) use self::buffer::Buffer;

/// Log target, either `stdout`, `stderr` or a custom pipe.
#[non_exhaustive]
pub enum Target {
/// Logs will be sent to standard output.
Stdout,
/// Logs will be sent to standard error.
Stderr,
/// Logs will be sent to a custom pipe.
Pipe(Box<dyn io::Write + Send + 'static>),
}

impl Default for Target {
fn default() -> Self {
Target::Stderr
}
}

impl fmt::Debug for Target {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::Stdout => "stdout",
Self::Stderr => "stderr",
Self::Pipe(_) => "pipe",
}
)
}
}

/// Log target, either `stdout`, `stderr` or a custom pipe.
///
/// Same as `Target`, except the pipe is wrapped in a mutex for interior mutability.
pub(super) enum WritableTarget {
/// Logs will be written to standard output.
#[allow(dead_code)]
WriteStdout,
/// Logs will be printed to standard output.
PrintStdout,
/// Logs will be written to standard error.
#[allow(dead_code)]
WriteStderr,
/// Logs will be printed to standard error.
PrintStderr,
/// Logs will be sent to a custom pipe.
Pipe(Box<Mutex<dyn io::Write + Send + 'static>>),
}

impl WritableTarget {
fn print(&self, buf: &Buffer) -> io::Result<()> {
use std::io::Write as _;
pub use target::Target;
use target::WritableTarget;

let buf = buf.as_bytes();
match self {
WritableTarget::WriteStdout => {
let stream = std::io::stdout();
let mut stream = stream.lock();
stream.write_all(buf)?;
stream.flush()?;
}
WritableTarget::PrintStdout => print!("{}", String::from_utf8_lossy(buf)),
WritableTarget::WriteStderr => {
let stream = std::io::stderr();
let mut stream = stream.lock();
stream.write_all(buf)?;
stream.flush()?;
}
WritableTarget::PrintStderr => eprint!("{}", String::from_utf8_lossy(buf)),
// Safety: If the target type is `Pipe`, `target_pipe` will always be non-empty.
WritableTarget::Pipe(pipe) => {
let mut stream = pipe.lock().unwrap();
stream.write_all(buf)?;
stream.flush()?;
}
}

Ok(())
}
}

impl fmt::Debug for WritableTarget {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::WriteStdout => "stdout",
Self::PrintStdout => "stdout",
Self::WriteStderr => "stderr",
Self::PrintStderr => "stderr",
Self::Pipe(_) => "pipe",
}
)
}
}
/// Whether or not to print styles to the target.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum WriteStyle {
Expand Down
96 changes: 96 additions & 0 deletions src/fmt/writer/target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/// Log target, either `stdout`, `stderr` or a custom pipe.
#[non_exhaustive]
pub enum Target {
/// Logs will be sent to standard output.
Stdout,
/// Logs will be sent to standard error.
Stderr,
/// Logs will be sent to a custom pipe.
Pipe(Box<dyn std::io::Write + Send + 'static>),
}

impl Default for Target {
fn default() -> Self {
Target::Stderr
}
}

impl std::fmt::Debug for Target {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Stdout => "stdout",
Self::Stderr => "stderr",
Self::Pipe(_) => "pipe",
}
)
}
}

/// Log target, either `stdout`, `stderr` or a custom pipe.
///
/// Same as `Target`, except the pipe is wrapped in a mutex for interior mutability.
pub(super) enum WritableTarget {
/// Logs will be written to standard output.
#[allow(dead_code)]
WriteStdout,
/// Logs will be printed to standard output.
PrintStdout,
/// Logs will be written to standard error.
#[allow(dead_code)]
WriteStderr,
/// Logs will be printed to standard error.
PrintStderr,
/// Logs will be sent to a custom pipe.
Pipe(Box<std::sync::Mutex<dyn std::io::Write + Send + 'static>>),
}

impl WritableTarget {
pub(super) fn print(&self, buf: &super::Buffer) -> std::io::Result<()> {
use std::io::Write as _;

let buf = buf.as_bytes();
match self {
WritableTarget::WriteStdout => {
let stream = std::io::stdout();
let mut stream = stream.lock();
stream.write_all(buf)?;
stream.flush()?;
}
WritableTarget::PrintStdout => print!("{}", String::from_utf8_lossy(buf)),
WritableTarget::WriteStderr => {
let stream = std::io::stderr();
let mut stream = stream.lock();
stream.write_all(buf)?;
stream.flush()?;
}
WritableTarget::PrintStderr => eprint!("{}", String::from_utf8_lossy(buf)),
// Safety: If the target type is `Pipe`, `target_pipe` will always be non-empty.
WritableTarget::Pipe(pipe) => {
let mut stream = pipe.lock().unwrap();
stream.write_all(buf)?;
stream.flush()?;
}
}

Ok(())
}
}

impl std::fmt::Debug for WritableTarget {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::WriteStdout => "stdout",
Self::PrintStdout => "stdout",
Self::WriteStderr => "stderr",
Self::PrintStderr => "stderr",
Self::Pipe(_) => "pipe",
}
)
}
}

0 comments on commit f4808e4

Please sign in to comment.