feat(print): add print module
This commit is contained in:
parent
436ad890d8
commit
bc7219755e
5 changed files with 528 additions and 3 deletions
34
examples/printer.rs
Normal file
34
examples/printer.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
use kxio::{kxprintln, print::Printer};
|
||||||
|
|
||||||
|
// Example using kxprintln macro
|
||||||
|
fn greet(printer: &Printer, name: &str) {
|
||||||
|
kxprintln!(printer, "Hello, {}!", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Production code example
|
||||||
|
let printer = Printer::standard();
|
||||||
|
kxprintln!(printer, "Macro says: Hello, {}!", "Carol");
|
||||||
|
greet(&printer, "Carol");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use kxio::print::TestPrint;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_printer() {
|
||||||
|
// Test code
|
||||||
|
let printer = Printer::test();
|
||||||
|
// Get reference to TestPrinter so we can make assertions
|
||||||
|
let test_print = printer.as_test().unwrap();
|
||||||
|
greet(&printer, "Bob");
|
||||||
|
assert_eq!(test_print.output(), "Hello, Bob!\n");
|
||||||
|
test_print.clear();
|
||||||
|
|
||||||
|
greet(&printer, "Dave");
|
||||||
|
assert_eq!(test_print.output(), "Hello, Dave!\n");
|
||||||
|
}
|
||||||
|
}
|
13
src/lib.rs
13
src/lib.rs
|
@ -1,14 +1,15 @@
|
||||||
//! # kxio
|
//! # kxio
|
||||||
//!
|
//!
|
||||||
//! `kxio` is a Rust library that provides injectable `FileSystem` and `Network`
|
//! `kxio` is a Rust library that provides injectable `FileSystem`, `Network` and `Printer`
|
||||||
//! resources to enhance the testability of your code. By abstracting system-level
|
//! resources to enhance the testability of your code. By abstracting system-level
|
||||||
//! interactions, `kxio` enables easier mocking and testing of code that relies on
|
//! interactions, `kxio` enables easier mocking and testing of code that relies on
|
||||||
//! file system and network operations.
|
//! file system, network and print operations.
|
||||||
//!
|
//!
|
||||||
//! ## Features
|
//! ## Features
|
||||||
//!
|
//!
|
||||||
//! - Filesystem Abstraction
|
//! - Filesystem Abstraction
|
||||||
//! - Network Abstraction
|
//! - Network Abstraction
|
||||||
|
//! - Print Abstraction
|
||||||
//! - Enhanced Testability
|
//! - Enhanced Testability
|
||||||
//!
|
//!
|
||||||
//! ## Filesystem
|
//! ## Filesystem
|
||||||
|
@ -30,6 +31,11 @@
|
||||||
//! comprehensive documentation and usage examples, please refer to
|
//! comprehensive documentation and usage examples, please refer to
|
||||||
//! <https://docs.rs/kxio/latest/kxio/net/>
|
//! <https://docs.rs/kxio/latest/kxio/net/>
|
||||||
//!
|
//!
|
||||||
|
//! ## Printer
|
||||||
|
//!
|
||||||
|
//! No, not a hardware printer, but console output via the family of `println` macros from the
|
||||||
|
//! Standard Library.
|
||||||
|
//!
|
||||||
//! ## Getting Started
|
//! ## Getting Started
|
||||||
//!
|
//!
|
||||||
//! Add `kxio` to your `Cargo.toml`:
|
//! Add `kxio` to your `Cargo.toml`:
|
||||||
|
@ -42,7 +48,7 @@
|
||||||
//! ## Usage
|
//! ## Usage
|
||||||
//!
|
//!
|
||||||
//! See the example [get.rs](https://git.kemitix.net/kemitix/kxio/src/branch/main/examples/get.rs) for an annotated example on how to use the `kxio` library.
|
//! See the example [get.rs](https://git.kemitix.net/kemitix/kxio/src/branch/main/examples/get.rs) for an annotated example on how to use the `kxio` library.
|
||||||
//! It covers both the `net` and `fs` modules.
|
//! It covers the `net`, `fs` and `print` modules.
|
||||||
//!
|
//!
|
||||||
//! ## Development
|
//! ## Development
|
||||||
//!
|
//!
|
||||||
|
@ -65,6 +71,7 @@
|
||||||
|
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
|
pub mod print;
|
||||||
mod result;
|
mod result;
|
||||||
|
|
||||||
pub use result::{Error, Result};
|
pub use result::{Error, Result};
|
||||||
|
|
73
src/print/macros.rs
Normal file
73
src/print/macros.rs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! kxprintln {
|
||||||
|
($printer:expr, $($arg:tt)*) => {{
|
||||||
|
$crate::print::Print::println_fmt(&$printer.clone(), format_args!($($arg)*))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! kxprint {
|
||||||
|
($printer:expr, $($arg:tt)*) => {{
|
||||||
|
$crate::print::Print::print_fmt(&$printer.clone(), format_args!($($arg)*))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! kxeprintln {
|
||||||
|
($printer:expr, $($arg:tt)*) => {{
|
||||||
|
$crate::print::Print::eprintln_fmt(&$printer.clone(), format_args!($($arg)*))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! kxeprint {
|
||||||
|
($printer:expr, $($arg:tt)*) => {{
|
||||||
|
$crate::print::Print::eprint_fmt(&$printer.clone(), format_args!($($arg)*))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::TestPrint;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_macro_with_ref_and_owned() {
|
||||||
|
// Test with reference
|
||||||
|
let printer = TestPrint::new();
|
||||||
|
kxprintln!(&printer, "ref test");
|
||||||
|
assert_eq!(printer.output(), "ref test\n");
|
||||||
|
printer.clear();
|
||||||
|
|
||||||
|
// Test with owned value
|
||||||
|
kxprintln!(printer, "owned test");
|
||||||
|
assert_eq!(printer.output(), "owned test\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_kxprint_macro() {
|
||||||
|
let printer = TestPrint::new();
|
||||||
|
kxprint!(printer, "Hello {}", "world");
|
||||||
|
assert_eq!(printer.output(), "Hello world");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_kxprintln_macro() {
|
||||||
|
let printer = TestPrint::new();
|
||||||
|
kxprintln!(printer, "Hello {}", "world");
|
||||||
|
assert_eq!(printer.output(), "Hello world\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_kxeprint_macro() {
|
||||||
|
let printer = TestPrint::new();
|
||||||
|
kxeprint!(printer, "Error: {}", "file not found");
|
||||||
|
assert_eq!(printer.stderr(), "Error: file not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_kxeprintln_macro() {
|
||||||
|
let printer = TestPrint::new();
|
||||||
|
kxeprintln!(printer, "Error: {}", "permission denied");
|
||||||
|
assert_eq!(printer.stderr(), "Error: permission denied\n");
|
||||||
|
}
|
||||||
|
}
|
343
src/print/mod.rs
Normal file
343
src/print/mod.rs
Normal file
|
@ -0,0 +1,343 @@
|
||||||
|
//! Provides an injectable interface for standard print operations.
|
||||||
|
//!
|
||||||
|
//! This module also includes macros for println and print operations that
|
||||||
|
//! are similar to the standard library but work with the Print trait.
|
||||||
|
//!
|
||||||
|
//! This module offers a trait-based abstraction over printing operations,
|
||||||
|
//! allowing for dependency injection and easier testing of code that performs
|
||||||
|
//! printing operations.
|
||||||
|
//!
|
||||||
|
//! # Examples
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! use kxio::print::{Print, StandardPrint};
|
||||||
|
//!
|
||||||
|
//! fn print_hello(printer: &impl Print) {
|
||||||
|
//! printer.println("Hello, World!");
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! let printer = StandardPrint;
|
||||||
|
//! print_hello(&printer);
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
mod macros;
|
||||||
|
mod printer;
|
||||||
|
|
||||||
|
pub use printer::Printer;
|
||||||
|
use std::fmt::Arguments;
|
||||||
|
|
||||||
|
/// Standard implementation of the Print trait that uses the std::print! and std::println! macros.
|
||||||
|
pub fn standard() -> Printer {
|
||||||
|
Printer::standard()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A no-op implementation of the Print trait that discards all output.
|
||||||
|
pub fn null() -> Printer {
|
||||||
|
Printer::null()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A test implementation that captures output in a String.
|
||||||
|
pub fn test() -> Printer {
|
||||||
|
Printer::test()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trait defining print operations that can be performed by implementors.
|
||||||
|
pub trait Print: Clone {
|
||||||
|
/// Prints a formatted line to the standard output.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `args` - Format arguments to print
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use kxio::print::{Print, StandardPrint};
|
||||||
|
///
|
||||||
|
/// let printer = StandardPrint;
|
||||||
|
/// printer.print_fmt(format_args!("Hello"));
|
||||||
|
/// ```
|
||||||
|
fn print_fmt(&self, args: Arguments<'_>);
|
||||||
|
|
||||||
|
/// Prints a formatted line followed by a newline to the standard output.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `args` - Format arguments to print
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use kxio::print::{Print, StandardPrint};
|
||||||
|
///
|
||||||
|
/// let printer = StandardPrint;
|
||||||
|
/// printer.println_fmt(format_args!("Hello"));
|
||||||
|
/// ```
|
||||||
|
fn println_fmt(&self, args: Arguments<'_>);
|
||||||
|
|
||||||
|
/// Prints a string slice to the standard output.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `s` - The string slice to print
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use kxio::print::{Print, StandardPrint};
|
||||||
|
///
|
||||||
|
/// let printer = StandardPrint;
|
||||||
|
/// printer.print("Hello");
|
||||||
|
/// ```
|
||||||
|
fn print(&self, s: &str) {
|
||||||
|
self.print_fmt(format_args!("{}", s));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints a string slice followed by a newline to the standard output.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `s` - The string slice to print
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use kxio::print::{Print, StandardPrint};
|
||||||
|
///
|
||||||
|
/// let printer = StandardPrint;
|
||||||
|
/// printer.println("Hello");
|
||||||
|
/// ```
|
||||||
|
fn println(&self, s: &str) {
|
||||||
|
self.println_fmt(format_args!("{}", s));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints a string slice to the standard error.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `s` - The string slice to print to stderr
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use kxio::print::{Print, StandardPrint};
|
||||||
|
///
|
||||||
|
/// let printer = StandardPrint;
|
||||||
|
/// printer.eprint("Error");
|
||||||
|
/// ```
|
||||||
|
fn eprint(&self, s: &str) {
|
||||||
|
self.eprint_fmt(format_args!("{}", s));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints a string slice followed by a newline to the standard error.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `s` - The string slice to print to stderr
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use kxio::print::{Print, StandardPrint};
|
||||||
|
///
|
||||||
|
/// let printer = StandardPrint;
|
||||||
|
/// printer.eprintln("Error");
|
||||||
|
/// ```
|
||||||
|
fn eprintln(&self, s: &str) {
|
||||||
|
self.eprintln_fmt(format_args!("{}", s));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints to stderr with a format string.
|
||||||
|
///
|
||||||
|
/// This method is the base method for printing to stderr. The other stderr printing
|
||||||
|
/// methods are implemented in terms of this one.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `args` - The format arguments to print
|
||||||
|
fn eprint_fmt(&self, args: Arguments<'_>);
|
||||||
|
|
||||||
|
/// Prints to stderr with a format string, followed by a newline.
|
||||||
|
///
|
||||||
|
/// This method is the base method for printing to stderr with a newline. The other stderr printing
|
||||||
|
/// methods are implemented in terms of this one.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `args` - The format arguments to print
|
||||||
|
fn eprintln_fmt(&self, args: Arguments<'_>);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Standard implementation of the Print trait that uses the std::print! and std::println! macros.
|
||||||
|
#[derive(Clone, Debug, Default, Copy)]
|
||||||
|
pub struct StandardPrint;
|
||||||
|
|
||||||
|
impl Print for StandardPrint {
|
||||||
|
fn print_fmt(&self, args: Arguments<'_>) {
|
||||||
|
std::print!("{}", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn println_fmt(&self, args: Arguments<'_>) {
|
||||||
|
std::println!("{}", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eprint_fmt(&self, args: Arguments<'_>) {
|
||||||
|
std::eprint!("{}", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eprintln_fmt(&self, args: Arguments<'_>) {
|
||||||
|
std::eprintln!("{}", args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A no-op implementation of the Print trait that discards all output.
|
||||||
|
#[derive(Clone, Debug, Default, Copy)]
|
||||||
|
pub struct NullPrint;
|
||||||
|
|
||||||
|
impl Print for NullPrint {
|
||||||
|
fn print_fmt(&self, _args: Arguments<'_>) {}
|
||||||
|
fn println_fmt(&self, _args: Arguments<'_>) {}
|
||||||
|
fn eprint_fmt(&self, _args: Arguments<'_>) {}
|
||||||
|
fn eprintln_fmt(&self, _args: Arguments<'_>) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A test implementation that captures output in a String.
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct TestPrint {
|
||||||
|
stdout: std::sync::Arc<std::sync::Mutex<String>>,
|
||||||
|
stderr: std::sync::Arc<std::sync::Mutex<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestPrint {
|
||||||
|
/// Creates a new TestPrint instance.
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
stdout: std::sync::Arc::new(std::sync::Mutex::new(String::new())),
|
||||||
|
stderr: std::sync::Arc::new(std::sync::Mutex::new(String::new())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the captured stdout output as a String.
|
||||||
|
pub fn output(&self) -> String {
|
||||||
|
self.stdout.lock().unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the captured stderr output as a String.
|
||||||
|
pub fn stderr(&self) -> String {
|
||||||
|
self.stderr.lock().unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears both the captured stdout and stderr output.
|
||||||
|
pub fn clear(&self) {
|
||||||
|
self.stdout.lock().unwrap().clear();
|
||||||
|
self.stderr.lock().unwrap().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Print for TestPrint {
|
||||||
|
fn print_fmt(&self, args: Arguments<'_>) {
|
||||||
|
(&self).print_fmt(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn println_fmt(&self, args: Arguments<'_>) {
|
||||||
|
(&self).println_fmt(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eprint_fmt(&self, args: Arguments<'_>) {
|
||||||
|
(&self).eprint_fmt(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eprintln_fmt(&self, args: Arguments<'_>) {
|
||||||
|
(&self).eprintln_fmt(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Print for &TestPrint {
|
||||||
|
fn print_fmt(&self, args: Arguments<'_>) {
|
||||||
|
let mut output = self.stdout.lock().unwrap();
|
||||||
|
output.push_str(&format!("{}", args));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn println_fmt(&self, args: Arguments<'_>) {
|
||||||
|
let mut output = self.stdout.lock().unwrap();
|
||||||
|
output.push_str(&format!("{}\n", args));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eprint_fmt(&self, args: Arguments<'_>) {
|
||||||
|
let mut output = self.stderr.lock().unwrap();
|
||||||
|
output.push_str(&format!("{}", args));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eprintln_fmt(&self, args: Arguments<'_>) {
|
||||||
|
let mut output = self.stderr.lock().unwrap();
|
||||||
|
output.push_str(&format!("{}\n", args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::{kxprint, kxprintln};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_standard_print() {
|
||||||
|
let printer = Printer::standard();
|
||||||
|
// Note: This will actually print to stdout
|
||||||
|
printer.println("This is a test");
|
||||||
|
kxprintln!(printer, "This is a {} test", "macro");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_null_print() {
|
||||||
|
let printer = Printer::null();
|
||||||
|
printer.println("This should not appear anywhere");
|
||||||
|
kxprintln!(printer, "This should also, {}", "not appear anywhere");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_test_print() {
|
||||||
|
let printer = Printer::test();
|
||||||
|
// we are interleaving printing, with assertions, so just extraxt the TestPrinter reference now
|
||||||
|
let test_print = printer.as_test().unwrap();
|
||||||
|
|
||||||
|
// Test stdout functions
|
||||||
|
printer.print("Hello");
|
||||||
|
kxprint!(printer, " ");
|
||||||
|
printer.println("World");
|
||||||
|
assert_eq!(test_print.output(), "Hello World\n");
|
||||||
|
|
||||||
|
// Test stderr functions
|
||||||
|
printer.eprint("Error: ");
|
||||||
|
printer.eprintln("something went wrong");
|
||||||
|
assert_eq!(test_print.stderr(), "Error: something went wrong\n");
|
||||||
|
|
||||||
|
// Test clear function clears both buffers
|
||||||
|
test_print.clear();
|
||||||
|
assert_eq!(test_print.output(), "");
|
||||||
|
assert_eq!(test_print.stderr(), "");
|
||||||
|
|
||||||
|
// Verify separate stdout/stderr streams
|
||||||
|
printer.println("info: running task");
|
||||||
|
printer.eprintln("error: task failed");
|
||||||
|
assert_eq!(test_print.output(), "info: running task\n");
|
||||||
|
assert_eq!(test_print.stderr(), "error: task failed\n");
|
||||||
|
|
||||||
|
test_print.clear();
|
||||||
|
printer.println("New message");
|
||||||
|
kxprintln!(printer, "second line");
|
||||||
|
assert_eq!(test_print.output(), "New message\nsecond line\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_print_in_function() {
|
||||||
|
fn print_message(printer: &Printer) {
|
||||||
|
printer.println("Test message");
|
||||||
|
kxprintln!(printer, "{} test message", "Second");
|
||||||
|
}
|
||||||
|
|
||||||
|
let printer = Printer::test();
|
||||||
|
let test_print = printer.as_test().unwrap();
|
||||||
|
print_message(&printer);
|
||||||
|
assert_eq!(test_print.output(), "Test message\nSecond test message\n");
|
||||||
|
}
|
||||||
|
}
|
68
src/print/printer.rs
Normal file
68
src/print/printer.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
use super::{NullPrint, Print, StandardPrint, TestPrint};
|
||||||
|
|
||||||
|
/// A wrapper struct that can contain any implementation of the Print trait
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum Printer {
|
||||||
|
Standard(StandardPrint),
|
||||||
|
Null(NullPrint),
|
||||||
|
Test(TestPrint),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Printer {
|
||||||
|
/// Creates a new Printer wrapping a StandardPrint implementation
|
||||||
|
pub fn standard() -> Self {
|
||||||
|
Self::Standard(StandardPrint)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new Printer wrapping a NullPrint implementation
|
||||||
|
pub fn null() -> Self {
|
||||||
|
Self::Null(NullPrint)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new Printer wrapping a TestPrint implementation
|
||||||
|
pub fn test() -> Self {
|
||||||
|
Self::Test(TestPrint::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the wrapped TestPrint implementation if this Printer contains one
|
||||||
|
pub fn as_test(&self) -> Option<&TestPrint> {
|
||||||
|
match self {
|
||||||
|
Self::Test(test_print) => Some(test_print),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Print for Printer {
|
||||||
|
fn print_fmt(&self, args: std::fmt::Arguments<'_>) {
|
||||||
|
match self {
|
||||||
|
Self::Standard(p) => p.print_fmt(args),
|
||||||
|
Self::Null(p) => p.print_fmt(args),
|
||||||
|
Self::Test(p) => p.print_fmt(args),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn println_fmt(&self, args: std::fmt::Arguments<'_>) {
|
||||||
|
match self {
|
||||||
|
Self::Standard(p) => p.println_fmt(args),
|
||||||
|
Self::Null(p) => p.println_fmt(args),
|
||||||
|
Self::Test(p) => p.println_fmt(args),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eprint_fmt(&self, args: std::fmt::Arguments<'_>) {
|
||||||
|
match self {
|
||||||
|
Self::Standard(p) => p.eprint_fmt(args),
|
||||||
|
Self::Null(p) => p.eprint_fmt(args),
|
||||||
|
Self::Test(p) => p.eprint_fmt(args),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eprintln_fmt(&self, args: std::fmt::Arguments<'_>) {
|
||||||
|
match self {
|
||||||
|
Self::Standard(p) => p.eprintln_fmt(args),
|
||||||
|
Self::Null(p) => p.eprintln_fmt(args),
|
||||||
|
Self::Test(p) => p.eprintln_fmt(args),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue