#![deny(
missing_docs,
missing_debug_implementations,
trivial_casts,
trivial_numeric_casts,
unsafe_code,
unstable_features,
unused_import_braces,
unused_qualifications,
// rustdoc::missing_doc_code_examples, // can be re-enabled when developing, but not useful as a strict rule
rustdoc::broken_intra_doc_links,
rustdoc::private_intra_doc_links,
rustdoc::missing_crate_level_docs,
rustdoc::invalid_codeblock_attributes,
rustdoc::invalid_html_tags,
rustdoc::bare_urls,
rustdoc::redundant_explicit_links,
rustdoc::unescaped_backticks
)]
#![allow(
clippy::wildcard_imports, // glob import > importing 20 items
clippy::enum_glob_use,
clippy::items_after_statements // if an item is only used locally, define it where it is needed
)]
#![doc = include_str!("../Readme.md")]
mod from_scanf;
mod macros;
mod parser;
pub use from_scanf::*;
pub use macros::*;
pub use parser::*;
pub mod advanced;
#[doc = include_str!("../Changelog.md")]
pub mod changelog {}
pub fn parse<'input, T: FromScanf<'input>>(input: &'input str) -> Option<T> {
Parser::<T>::new().parse(input)
}
#[cfg(test)]
mod tests {
#[macro_export]
macro_rules! assert_panic_message_eq {
( $block:block, $message:literal $(,)? ) => {
let Err(error) = std::panic::catch_unwind(move || $block) else {
panic!("code {} did not panic", stringify!($block));
};
if let Some(s) = error.downcast_ref::<&'static str>() {
assert_eq!(*s, $message);
} else if let Some(s) = error.downcast_ref::<String>() {
assert_eq!(s, $message);
} else {
panic!("unexpected panic payload: {:?}", error);
}
};
( $expression:expr, $message:literal $(,)? ) => {
assert_panic_message_eq!(
{
$expression; },
$message
);
};
( $statement:stmt, $message:literal $(,)? ) => {
assert_panic_message_eq!({ $statement }, $message);
};
}
}