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 bystd
so enabled by default): EnablesWriteStringFn
andConcatWriter
types.std
(enabled by default): EnablesIoWriter
,{Try}Write{CStr|CString|CCharPtr}Fn
,define_panic_hook
anddefine_init_panic_hook
.
§Similar crates
web-log
providesprint
,println
,eprint
,eprintln
, requires wasm-bindgen.wasm-rs-dbg
providesdbg
, requires web-sys.console_log
provides logging withtrace
,debug
,warn
,error
etc., requires log and web-sys.console_error_panic_hook
provides 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
dbg
macro 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
flush
macro that callsflush
method of the specified writer. - define_
init_ panic_ hook - Defines
init_panic_hook
function 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_hook
function that can be used as panic hook that uses the specified writer. - define_
print - Defines
print
macro 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
println
macro that defines a println macro that uses the specified writer. - define_
try_ dbg - Defines
try_dbg
macro 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_flush
macro that callsflush
method of the specified writer. - define_
try_ print - Defines
try_print
macro that defines a fallible print macro that uses the specified writer. - define_
try_ println - Defines
try_println
macro 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_hook
that 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_str
once with a combined string. - Concat
Writer - A writer that calls
write_str
once with a combined string. - FlushFn
- A wrapper for flush function
for<R> FnMut(*const c_char) -> R
. - FmtTry
Writer - A writer that calls
write_str
for each formatted chunk, but do not require allocations. - FmtWriter
- A writer that calls
write_str
for each formatted chunk, but do not require allocations. - IoTry
Writer - A writer that uses
write_bytes
and has bothwrite
andflush
methods. - IoWriter
- A writer that uses
write_bytes
and has bothwrite
andflush
methods. - 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
ConcatWriter
to convert wrapped function result toResult
<T, NeverError>
with error unwrapping. - Expect
FmtWrite Result - A helper trait used by
FmtWriter
to convert wrapped function result tofmt::Result
with error unwrapping. - Expect
IoFlush Result - A helper trait used by
IoWriter
flush method to convert wrapped function result toio::Result
with error unwrapping. - Expect
IoWrite Result - A helper trait used by
IoWriter
write method to convert wrapped function result toio::Result
with error unwrapping. - Flush
- A trait for objects which can flush written data on request.
- Into
Concat Write Result - A helper trait used by
ConcatTryWriter
to convert wrapped function result toResult
<T, E>
. - Into
FmtWrite Result - A helper trait used by
FmtTryWriter
to convert wrapped function result tofmt::Result
with error propagation. - Into
IoFlush Result - A helper trait used by
IoTryWriter
flush method to convert wrapped function result toio::Result
with error propagation. - Into
IoWrite Result - A helper trait used by
IoTryWriter
write method to convert wrapped function result toio::Result
with 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
str
returning a specific output. - Write
StrAs Bytes - A trait for objects which should implement
WriteStr
using theirWriteBytes
implementation.