Expand description
The custom-print crate helps you to define print, println and dbg macros
in wasm and customize them for other targets without any dependencies.
§About
This crate helps you to define print-like macros, dbg and panic_hook
on wasm32-unknown-unknown target without wasm-bindgen dependency.
Also, it can be used on another targets to override default std write-like macros,
add try_ macros variants, or to specify panic hook function.
It works on stable Rust,
supports no-alloc and no-std environments and has no dependencies.
In most cases it is suggested to use macros
define_macros, define_macro or define_init_panic_hook.
These macros define macros or functions with the specified names that use
FmtWriter, FmtTryWriter, ConcatWriter, ConcatTryWriter,
IoWriter or IoTryWriter with the specified closure, unsafe function or extern function.
§Usage
First, add the following to your Cargo.toml:
[dependencies]
custom-print = "1.0.0"This crate depends on the standard library by default.
To use this crate in a #![no_std] context but with heap-allocations enabled,
use default-features = false in your Cargo.toml as shown below:
[dependencies.custom-print]
version = "1.0.0"
default-features = false
features = ["alloc"]§Examples
An example with an extern functions that takes a UTF-8 chars pointer and byte length
with no std prelude:
#![no_std]
extern crate std;
custom_print::define_macros!({ print, println },
concat, extern "C" fn console_log(_: *const u8, _: usize));
custom_print::define_macros!({ eprint, eprintln, dbg },
concat, extern "C" fn console_warn(_: *const u8, _: usize));
custom_print::define_init_panic_hook!(
concat, extern "C" fn console_error(_: *const u8, _: usize));
fn main() {
init_panic_hook();
println!("println");
print!("print");
eprintln!("eprintln");
eprint!("eprint");
dbg!("dbg");
}An example with a closure that takes an str reference
in no_std and no_alloc context:
#![no_std]
custom_print::define_macros!({ print, println }, fmt, |_value: &str| { /* ... */ });
fn main() {
println!("println");
print!("print");
}An example with a function that takes a c_char pointer and overriding
std::print and std::println functions:
fn write(_value: *const std::os::raw::c_char) { /* ... */ }
custom_print::define_macros!({ cprint, cprintln }, concat, crate::write);
macro_rules! print { ($($args:tt)*) => { cprint!($($args)*); } }
macro_rules! println { ($($args:tt)*) => { cprintln!($($args)*); } }
fn main() {
println!("println");
print!("print");
}Macro generation macros support specifying custom attributes, so you can re-export the generated macros and use them in other crates:
// foo crate:
custom_print::define_macros!(
#[macro_export] { print, println, cprint, cprintln },
fmt, |_value: &str| { /* ... */ }
);
fn func() {
cprintln!("cprintln");
cprint!("cprint");
}
// bar crate:
fn main() {
foo::println!("println");
foo::print!("print");
}You can find more usage examples in the tests and examples repository folders.
§Macro expansion
The example with define_macros and define_init_panic_hook with extern functions:
#![no_std]
extern crate std;
custom_print::define_macros!({ print, println, try_println },
concat, extern "C" fn console_log(_: *const u8, _: usize));
custom_print::define_macros!({ eprint, eprintln, dbg },
concat, extern "C" fn console_warn(_: *const u8, _: usize));
custom_print::define_init_panic_hook!(
concat, extern "C" fn console_error(_: *const u8, _: usize));
fn main() {
init_panic_hook();
println!("Greetings from println");
let _ = try_println!("Greetings from try_println");
eprintln!("Greetings from eprintln");
let _ = dbg!("Greetings from dbg");
}partially expands to:
fn init_panic_hook() {
fn panic_hook(info: &::std::panic::PanicInfo<'_>) {
::core::writeln!(
::custom_print::ConcatWriter::from_closure({
extern "C" { fn console_error(_: *const u8, _: usize); }
|arg1: *const u8, arg2: usize| unsafe { console_error(arg1, arg2) }
}),
"{}",
info
).expect("failed writing panic info");
}
::std::panic::set_hook(::std::boxed::Box::new(panic_hook))
}
fn main() {
init_panic_hook();
::core::writeln!(
::custom_print::ConcatWriter::from_closure({
extern "C" { fn console_log(_: *const u8, _: usize); }
|arg1: *const u8, arg2: usize| unsafe { console_log(arg1, arg2) }
}),
"Greetings from println"
).expect("failed writing");
let _ = ::core::writeln!(
::custom_print::ConcatTryWriter::from_closure({
extern "C" { fn console_log(_: *const u8, _: usize); }
|arg1: *const u8, arg2: usize| unsafe { console_log(arg1, arg2) }
}),
"Greetings from try_println"
);
::core::writeln!(
::custom_print::ConcatWriter::from_closure({
extern "C" { fn console_warn(_: *const u8, _: usize); }
|arg1: *const u8, arg2: usize| unsafe { console_warn(arg1, arg2) }
}),
"Greetings from eprintln"
).expect("failed writing");
let _ = ::custom_print::dbgwrite!(
::core::writeln,
::custom_print::ConcatWriter::from_closure({
extern "C" { fn console_error(_: *const u8, _: usize); }
|arg1: *const u8, arg2: usize| unsafe { console_error(arg1, arg2) }
}),
expect,
":?",
"Greetings from dbg"
);
}§Feature Flags
alloc(implied bystdso enabled by default): EnablesWriteStringFnandConcatWritertypes.std(enabled by default): EnablesIoWriter,{Try}Write{CStr|CString|CCharPtr}Fn,define_panic_hookanddefine_init_panic_hook.
§Similar crates
web-logprovidesprint,println,eprint,eprintln, requires wasm-bindgen.wasm-rs-dbgprovidesdbg, requires web-sys.console_logprovides logging withtrace,debug,warn,erroretc., requires log and web-sys.console_error_panic_hookprovides panic_hook and panic hook set functions, requires wasm-bindgen.
§Troubleshooting
§Macro name is ambiguous
Errors like
`println` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
occur because of the inability to overwrite standard rust macros
in textual scope with macro-expanded macros.
Use can use proxy macros to replace std macros in textual scope:
custom_print::define_macro!(cprintln, once: write_fn);
macro_rules! println { ($($args:tt)*) => { cprintln!($($args)*); } }Alternatively, use can override macro in the path-based scope:
custom_print::define_macro!(cprintln, once: write_fn);
use cprintln as println;See define_macro for more details.
§Println, dbg and others do nothing in submodules
It looks like you have overridden print-like macros in the path-based scope,
but you have not overridden them in submodules.
Use proxy macros as it shown above
or do not forget to override it in submodules.
custom_print::define_macro!(cprintln, once: write_fn);
use cprintln as println;
mod submodule {
use cprintln as println;
}You can always use cargo expand to find out where the problem is.
§The trait bound [closure]: IntoWriteFn<_> is not satisfied
Errors like:
the trait bound `...: IntoWriteFn<_>` is not satisfied or
the trait bound `...: IntoTryWriteFn<_>` is not satisfied,
with note: required by ``...Writer::<F1>::from_closure ``
errors occur because of the inability to determine
the appropriate type of wrapper for the closure.
Specify closure arguments if you haven’t already,
or use helper closure that takes acceptable arguments (&str, &[u8], etc.)
and convert them to the arguments your function requires.
§License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
§Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Macros§
- dbgwrite
- Prints and returns the value of a given expression for quick and dirty debugging with the specified write macro, writer, format and error-handling policy.
- define_
dbg - Defines
dbgmacro that prints and returns the value of a given expression for quick and dirty debugging. - define_
dbglike - Defines a
dbg-like macro with a given name that uses specified write macro, error-handling policy, format string and writer. - define_
flush - Defines
flushmacro that callsflushmethod of the specified writer. - define_
init_ panic_ hook - Defines
init_panic_hookfunction that set panic hook with the specified writer. - define_
macro - Defines custom
print-like anddbg-like macro. - define_
macros - Defines multiple
print-like anddbg-like macros. - define_
panic_ hook - Defines
panic_hookfunction that can be used as panic hook that uses the specified writer. - define_
print - Defines
printmacro that defines a print macro that uses the specified writer. - define_
printlike - Defines a
print-like macro with a given name that uses specified write macro, error-handling policy and writer. - define_
println - Defines
printlnmacro that defines a println macro that uses the specified writer. - define_
try_ dbg - Defines
try_dbgmacro that prints and returns the value of a given expression wrapped in for quick and dirty debugging or return an error if write failed. - define_
try_ flush - Defines
try_flushmacro that callsflushmethod of the specified writer. - define_
try_ print - Defines
try_printmacro that defines a fallible print macro that uses the specified writer. - define_
try_ println - Defines
try_printlnmacro that defines a fallible println macro that uses the specified writer. - define_
try_ writer - Defines a fallible writer from writer expression arguments or from the provided one.
- define_
writer - Defines a writer from writer expression arguments or from the provided one.
- define_
writer_ expr - Defines a writer expression from another expression, unsafe function or extern function.
- init_
panic_ hook - Sets
panic_hookthat uses the specified writer. - write
- Calls another write macro with the specified writer, arguments and error-handling policy.
Structs§
- Concat
TryWriter - A writer that calls
write_stronce with a combined string. - Concat
Writer - A writer that calls
write_stronce with a combined string. - FlushFn
- A wrapper for flush function
for<R> FnMut(*const c_char) -> R. - FmtTry
Writer - A writer that calls
write_strfor each formatted chunk, but do not require allocations. - FmtWriter
- A writer that calls
write_strfor each formatted chunk, but do not require allocations. - IoTry
Writer - A writer that uses
write_bytesand has bothwriteandflushmethods. - IoWriter
- A writer that uses
write_bytesand has bothwriteandflushmethods. - TryWriteC
Char PtrFn - A wrapper for write functions
for<R> FnMut(*const c_char) -> R. - TryWriteC
StrFn - A wrapper for write functions
for<R> FnMut(&CStr) -> R. - TryWriteC
String Fn - A wrapper for write functions
for<R> FnMut(CString) -> R. - Write
Bytes Fn - A wrapper for write functions
for<R> FnMut(&[u8]) -> R. - WriteC
Char PtrFn - A wrapper for write functions
for<R> FnMut(*const c_char) -> R. - WriteC
StrFn - A wrapper for write functions
for<R> FnMut(&CStr) -> R. - WriteC
String Fn - A wrapper for write functions
for<R> FnMut(CString) -> R. - Write
LenPtr Fn - A wrapper for write functions
for<R> FnMut(usize, *const u8) -> R. - Write
PtrLen Fn - A wrapper for write functions
for<R> FnMut(*const u8, usize) -> R. - Write
StrFn - A wrapper for write functions
for<R> FnMut(&str) -> R. - Write
String Fn - A wrapper for write functions
for<R> FnMut(String) -> R.
Enums§
- Never
Error - A helper error type that cannot be instantiated.
Traits§
- Expect
Concat Write Result - A helper trait used by
ConcatWriterto convert wrapped function result toResult<T, NeverError>with error unwrapping. - Expect
FmtWrite Result - A helper trait used by
FmtWriterto convert wrapped function result tofmt::Resultwith error unwrapping. - Expect
IoFlush Result - A helper trait used by
IoWriterflush method to convert wrapped function result toio::Resultwith error unwrapping. - Expect
IoWrite Result - A helper trait used by
IoWriterwrite method to convert wrapped function result toio::Resultwith error unwrapping. - Flush
- A trait for objects which can flush written data on request.
- Into
Concat Write Result - A helper trait used by
ConcatTryWriterto convert wrapped function result toResult<T, E>. - Into
FmtWrite Result - A helper trait used by
FmtTryWriterto convert wrapped function result tofmt::Resultwith error propagation. - Into
IoFlush Result - A helper trait used by
IoTryWriterflush method to convert wrapped function result toio::Resultwith error propagation. - Into
IoWrite Result - A helper trait used by
IoTryWriterwrite method to convert wrapped function result toio::Resultwith error propagation. - Into
TryWrite Fn - A trait used to inference type of fallible write closure wrapper.
- Into
Write Fn - A trait used to inference type of write closure wrapper.
- Write
Bytes - A trait for objects which can write bytes returning a specific output.
- Write
Str - A trait for objects which can write
strreturning a specific output. - Write
StrAs Bytes - A trait for objects which should implement
WriteStrusing theirWriteBytesimplementation.