Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions crates/anstream/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,3 @@ impl anstyle_wincon::WinconStream for Buffer {
self.0.write_colored(fg, bg, data)
}
}

#[cfg(all(windows, feature = "wincon"))]
impl anstyle_wincon::WinconStream for &'_ mut Buffer {
fn write_colored(
&mut self,
fg: Option<anstyle::AnsiColor>,
bg: Option<anstyle::AnsiColor>,
data: &[u8],
) -> std::io::Result<usize> {
(**self).write_colored(fg, bg, data)
}
}
202 changes: 101 additions & 101 deletions crates/anstream/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,123 +11,115 @@ pub trait RawStream:
{
}

impl<T: RawStream + ?Sized> RawStream for &mut T {}
impl<T: RawStream + ?Sized> RawStream for Box<T> {}

impl RawStream for dyn std::io::Write {}
impl RawStream for dyn std::io::Write + Send {}
impl RawStream for dyn std::io::Write + Send + Sync {}

impl RawStream for std::io::Stdout {}

impl RawStream for std::io::StdoutLock<'_> {}

impl RawStream for &'_ mut std::io::StdoutLock<'_> {}

impl RawStream for std::io::Stderr {}

impl RawStream for std::io::StderrLock<'_> {}

impl RawStream for &'_ mut std::io::StderrLock<'_> {}

impl RawStream for Box<dyn std::io::Write> {}

impl RawStream for &'_ mut Box<dyn std::io::Write> {}

impl RawStream for Vec<u8> {}

impl RawStream for &'_ mut Vec<u8> {}

impl RawStream for std::fs::File {}

impl RawStream for &'_ mut std::fs::File {}

#[allow(deprecated)]
impl RawStream for crate::Buffer {}

#[allow(deprecated)]
impl RawStream for &'_ mut crate::Buffer {}

/// Trait to determine if a descriptor/handle refers to a terminal/tty.
pub trait IsTerminal: private::Sealed {
/// Returns `true` if the descriptor/handle refers to a terminal/tty.
fn is_terminal(&self) -> bool;
}

impl IsTerminal for std::io::Stdout {
impl<T: IsTerminal + ?Sized> IsTerminal for &T {
#[inline]
fn is_terminal(&self) -> bool {
is_terminal_polyfill::IsTerminal::is_terminal(self)
T::is_terminal(&**self)
}
}

impl IsTerminal for std::io::StdoutLock<'_> {
impl<T: IsTerminal + ?Sized> IsTerminal for &mut T {
#[inline]
fn is_terminal(&self) -> bool {
is_terminal_polyfill::IsTerminal::is_terminal(self)
T::is_terminal(&**self)
}
}

impl IsTerminal for &'_ mut std::io::StdoutLock<'_> {
impl<T: IsTerminal + ?Sized> IsTerminal for Box<T> {
#[inline]
fn is_terminal(&self) -> bool {
(**self).is_terminal()
T::is_terminal(&**self)
}
}

impl IsTerminal for std::io::Stderr {
impl IsTerminal for std::io::Stdout {
#[inline]
fn is_terminal(&self) -> bool {
is_terminal_polyfill::IsTerminal::is_terminal(self)
}
}

impl IsTerminal for std::io::StderrLock<'_> {
impl IsTerminal for std::io::StdoutLock<'_> {
#[inline]
fn is_terminal(&self) -> bool {
is_terminal_polyfill::IsTerminal::is_terminal(self)
}
}

impl IsTerminal for &'_ mut std::io::StderrLock<'_> {
impl IsTerminal for std::io::Stderr {
#[inline]
fn is_terminal(&self) -> bool {
(**self).is_terminal()
is_terminal_polyfill::IsTerminal::is_terminal(self)
}
}

impl IsTerminal for Box<dyn std::io::Write> {
impl IsTerminal for std::io::StderrLock<'_> {
#[inline]
fn is_terminal(&self) -> bool {
false
is_terminal_polyfill::IsTerminal::is_terminal(self)
}
}

impl IsTerminal for &'_ mut Box<dyn std::io::Write> {
impl IsTerminal for std::fs::File {
#[inline]
fn is_terminal(&self) -> bool {
false
is_terminal_polyfill::IsTerminal::is_terminal(self)
}
}

impl IsTerminal for Vec<u8> {
impl IsTerminal for dyn std::io::Write {
#[inline]
fn is_terminal(&self) -> bool {
false
}
}

impl IsTerminal for &'_ mut Vec<u8> {
impl IsTerminal for dyn std::io::Write + Send {
#[inline]
fn is_terminal(&self) -> bool {
false
}
}

impl IsTerminal for std::fs::File {
impl IsTerminal for dyn std::io::Write + Send + Sync {
#[inline]
fn is_terminal(&self) -> bool {
is_terminal_polyfill::IsTerminal::is_terminal(self)
false
}
}

impl IsTerminal for &'_ mut std::fs::File {
impl IsTerminal for Vec<u8> {
#[inline]
fn is_terminal(&self) -> bool {
(**self).is_terminal()
false
}
}

Expand All @@ -139,14 +131,6 @@ impl IsTerminal for crate::Buffer {
}
}

#[allow(deprecated)]
impl IsTerminal for &'_ mut crate::Buffer {
#[inline]
fn is_terminal(&self) -> bool {
(**self).is_terminal()
}
}

/// Lock a stream
pub trait AsLockedWrite: private::Sealed {
/// Locked writer type
Expand All @@ -158,109 +142,125 @@ pub trait AsLockedWrite: private::Sealed {
fn as_locked_write(&mut self) -> Self::Write<'_>;
}

impl AsLockedWrite for std::io::Stdout {
type Write<'w> = std::io::StdoutLock<'w>;
impl<T: AsLockedWrite + ?Sized> AsLockedWrite for &mut T {
type Write<'w>
= <T as AsLockedWrite>::Write<'w>
where
Self: 'w;

#[inline]
fn as_locked_write(&mut self) -> Self::Write<'_> {
self.lock()
T::as_locked_write(&mut **self)
}
}

impl AsLockedWrite for std::io::StdoutLock<'static> {
type Write<'w> = &'w mut Self;
impl<T: AsLockedWrite + ?Sized> AsLockedWrite for Box<T> {
type Write<'w>
= <T as AsLockedWrite>::Write<'w>
where
Self: 'w;

#[inline]
fn as_locked_write(&mut self) -> Self::Write<'_> {
self
T::as_locked_write(&mut **self)
}
}

impl AsLockedWrite for std::io::Stderr {
type Write<'w> = std::io::StderrLock<'w>;
impl AsLockedWrite for std::io::Stdout {
type Write<'w> = std::io::StdoutLock<'w>;

#[inline]
fn as_locked_write(&mut self) -> Self::Write<'_> {
self.lock()
}
}

impl AsLockedWrite for std::io::StderrLock<'static> {
type Write<'w> = &'w mut Self;

#[inline]
fn as_locked_write(&mut self) -> Self::Write<'_> {
self
}
}

impl AsLockedWrite for Box<dyn std::io::Write> {
type Write<'w> = &'w mut Self;

#[inline]
fn as_locked_write(&mut self) -> Self::Write<'_> {
self
}
}

impl AsLockedWrite for Vec<u8> {
type Write<'w> = &'w mut Self;
impl AsLockedWrite for std::io::Stderr {
type Write<'w> = std::io::StderrLock<'w>;

#[inline]
fn as_locked_write(&mut self) -> Self::Write<'_> {
self
self.lock()
}
}

impl AsLockedWrite for std::fs::File {
type Write<'w> = &'w mut Self;

#[inline]
fn as_locked_write(&mut self) -> Self::Write<'_> {
self
}
macro_rules! impl_default_locked_write {
($( $(#[$attr:meta])* $t:ty),* $(,)?) => {
$(
$(#[$attr])*
impl AsLockedWrite for $t {
type Write<'w> = &'w mut Self where Self: 'w;

#[inline]
fn as_locked_write(&mut self) -> Self::Write<'_> {
self
}
}
)*
};
}

#[allow(deprecated)]
impl AsLockedWrite for crate::Buffer {
type Write<'w> = &'w mut Self;

#[inline]
fn as_locked_write(&mut self) -> Self::Write<'_> {
self
}
}
impl_default_locked_write!(
dyn std::io::Write,
dyn std::io::Write + Send,
dyn std::io::Write + Send + Sync,
std::io::StdoutLock<'_>,
std::io::StderrLock<'_>,
Vec<u8>,
std::fs::File,
#[allow(deprecated)]
crate::Buffer,
);

mod private {
pub trait Sealed {}

impl<T: Sealed + ?Sized> Sealed for &T {}
impl<T: Sealed + ?Sized> Sealed for &mut T {}
impl<T: Sealed + ?Sized> Sealed for Box<T> {}

impl Sealed for dyn std::io::Write {}
impl Sealed for dyn std::io::Write + Send {}
impl Sealed for dyn std::io::Write + Send + Sync {}

impl Sealed for std::io::Stdout {}

impl Sealed for std::io::StdoutLock<'_> {}

impl Sealed for &'_ mut std::io::StdoutLock<'_> {}

impl Sealed for std::io::Stderr {}

impl Sealed for std::io::StderrLock<'_> {}

impl Sealed for &'_ mut std::io::StderrLock<'_> {}
impl Sealed for Vec<u8> {}

impl Sealed for Box<dyn std::io::Write> {}
impl Sealed for std::fs::File {}

impl Sealed for &'_ mut Box<dyn std::io::Write> {}
#[allow(deprecated)]
impl Sealed for crate::Buffer {}
}

impl Sealed for Vec<u8> {}
#[cfg(test)]
mod tests {
use super::*;

impl Sealed for &'_ mut Vec<u8> {}
fn assert_raw_stream<T: RawStream>() {}

impl Sealed for std::fs::File {}
#[test]
fn raw_streams() {
assert_raw_stream::<Box<dyn std::io::Write>>();
assert_raw_stream::<Box<dyn std::io::Write + 'static>>();
assert_raw_stream::<Box<dyn std::io::Write + Send>>();
assert_raw_stream::<Box<dyn std::io::Write + Send + Sync>>();

impl Sealed for &'_ mut std::fs::File {}
assert_raw_stream::<&mut (dyn std::io::Write)>();
assert_raw_stream::<&mut (dyn std::io::Write + 'static)>();
assert_raw_stream::<&mut (dyn std::io::Write + Send)>();
assert_raw_stream::<&mut (dyn std::io::Write + Send + Sync)>();

#[allow(deprecated)]
impl Sealed for crate::Buffer {}
assert_raw_stream::<Vec<u8>>();
assert_raw_stream::<&mut Vec<u8>>();

#[allow(deprecated)]
impl Sealed for &'_ mut crate::Buffer {}
assert_raw_stream::<std::fs::File>();
assert_raw_stream::<&mut std::fs::File>();
}
}
2 changes: 1 addition & 1 deletion crates/anstyle-wincon/src/ansi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Low-level ANSI-styling

/// Write ANSI colored text to the stream
pub fn write_colored<S: std::io::Write>(
pub fn write_colored<S: std::io::Write + ?Sized>(
stream: &mut S,
fg: Option<anstyle::AnsiColor>,
bg: Option<anstyle::AnsiColor>,
Expand Down
Loading