use core::convert::Infallible;
use std::collections::{BTreeMap, BTreeSet};
use ufmt::{derive::uDebug, uDebug, uWrite, uwrite, uwriteln, Formatter};
macro_rules! uformat {
($($tt:tt)*) => {{
let mut s = String::new();
#[allow(unreachable_code)]
match ufmt::uwrite!(&mut s, $($tt)*) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}};
}
macro_rules! cmp {
($($tt:tt)*) => {
assert_eq!(
uformat!($($tt)*),
Ok(format!($($tt)*)),
)
}
}
#[test]
fn core() {
cmp!("{:?}", None::<i32>);
cmp!("{:#?}", None::<i32>);
cmp!("{:?}", Some(0));
cmp!("{:#?}", Some(0));
cmp!("{:?}", Ok::<_, ()>(1));
cmp!("{:#?}", Ok::<_, ()>(1));
cmp!("{:?}", Err::<(), _>(2));
cmp!("{:#?}", Err::<(), _>(2));
}
#[test]
fn recursion() {
#[derive(uDebug, Debug)]
struct Node {
value: i32,
next: Option<Box<Node>>,
}
fn x() -> Node {
let tail = Node {
value: 0,
next: None,
};
Node {
value: 1,
next: Some(Box::new(tail)),
}
}
cmp!("{:?}", x());
cmp!("{:#?}", x());
}
#[test]
fn uxx() {
cmp!("{}", 0u8);
cmp!("{}", 10u8);
cmp!("{}", 100u8);
cmp!("{}", u8::max_value());
cmp!("{}", u16::max_value());
cmp!("{}", u32::max_value());
cmp!("{}", u64::max_value());
cmp!("{}", u128::max_value());
cmp!("{}", usize::max_value());
}
#[test]
fn ixx() {
cmp!("{}", 0i8);
cmp!("{}", 10i8);
cmp!("{}", 100i8);
cmp!("{}", i8::min_value());
cmp!("{}", i8::max_value());
cmp!("{}", i16::min_value());
cmp!("{}", i16::max_value());
cmp!("{}", i32::min_value());
cmp!("{}", i32::max_value());
cmp!("{}", i64::min_value());
cmp!("{}", i64::max_value());
cmp!("{}", i128::min_value());
cmp!("{}", i128::max_value());
cmp!("{}", isize::min_value());
cmp!("{}", isize::max_value());
}
#[test]
fn fmt() {
cmp!("Hello, world!");
cmp!("The answer is {}", 42);
}
#[test]
fn map() {
fn x() -> BTreeMap<i32, i32> {
let mut m = BTreeMap::new();
m.insert(1, 2);
m.insert(3, 4);
m
}
cmp!("{:?}", BTreeMap::<(), ()>::new());
cmp!("{:?}", x());
cmp!("{:#?}", BTreeMap::<(), ()>::new());
cmp!("{:#?}", x());
}
#[test]
fn set() {
fn x() -> BTreeSet<i32> {
let mut m = BTreeSet::new();
m.insert(1);
m.insert(3);
m
}
cmp!("{:?}", BTreeSet::<()>::new());
cmp!("{:?}", x());
cmp!("{:#?}", BTreeSet::<()>::new());
cmp!("{:#?}", x());
}
#[test]
fn struct_() {
#[derive(Debug, uDebug)]
struct Braces {}
#[derive(Debug, uDebug)]
struct Parens();
#[derive(Debug, Default, uDebug)]
struct I32(i32);
#[derive(Debug, Default, uDebug)]
struct Tuple(i32, i32);
#[derive(Debug, Default, uDebug)]
struct Pair {
x: i32,
y: i32,
}
#[derive(Debug, Default, uDebug)]
struct Nested {
first: Pair,
second: Pair,
}
cmp!("{:?}", Braces {});
cmp!("{:?}", Parens());
cmp!("{:?}", I32::default());
cmp!("{:?}", Tuple::default());
cmp!("{:?}", Pair::default());
cmp!("{:?}", Nested::default());
cmp!("{:#?}", Braces {});
cmp!("{:#?}", Parens());
cmp!("{:#?}", I32::default());
cmp!("{:#?}", Tuple::default());
cmp!("{:#?}", Pair::default());
cmp!("{:#?}", Nested::default());
}
#[test]
fn enum_() {
#[derive(Debug, uDebug)]
enum X {
A,
B(u8, u16),
C { x: u8, y: u16 },
}
cmp!("{:?}", X::A);
cmp!("{:?}", X::B(0, 1));
cmp!("{:?}", X::C { x: 0, y: 1 });
cmp!("{:#?}", X::A);
cmp!("{:#?}", X::B(0, 1));
cmp!("{:#?}", X::C { x: 0, y: 1 });
}
#[test]
fn ptr() {
cmp!("{:?}", 1 as *const u8);
cmp!("{:?}", 0xf as *const u8);
cmp!("{:?}", 0xff as *const u8);
cmp!("{:?}", 0xfff as *const u8);
cmp!("{:?}", 0xffff as *const u8);
cmp!("{:?}", 0xfffff as *const u8);
cmp!("{:?}", 0xffffff as *const u8);
cmp!("{:?}", 0xfffffff as *const u8);
cmp!("{:?}", 0xffffffff as *const u8);
#[cfg(target_pointer_width = "64")]
cmp!("{:?}", 0xfffffffff as *const u8);
}
#[test]
fn tuples() {
cmp!("{:?}", ());
cmp!("{:?}", (1,));
cmp!("{:?}", (1, 2));
cmp!("{:?}", (1, 2, 3));
cmp!("{:?}", (1, 2, 3, 4));
cmp!("{:?}", (1, 2, 3, 4, 5));
cmp!("{:?}", (1, 2, 3, 4, 5, 6));
cmp!("{:?}", (1, 2, 3, 4, 5, 6, 7));
cmp!("{:?}", (1, 2, 3, 4, 5, 6, 7, 8));
cmp!("{:?}", (1, 2, 3, 4, 5, 6, 7, 8, 9));
cmp!("{:?}", (1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
cmp!("{:?}", (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
cmp!("{:?}", (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
cmp!("{:#?}", ());
cmp!("{:#?}", (1,));
cmp!("{:#?}", (1, 2));
}
#[test]
fn slice() {
cmp!("{:?}", [0; 0]);
cmp!("{:?}", [0]);
cmp!("{:?}", [0, 1]);
cmp!("{:#?}", [0; 0]);
cmp!("{:#?}", [0]);
cmp!("{:#?}", [0, 1]);
}
#[test]
fn uwriteln() {
let mut s = String::new();
uwriteln!(&mut s, "Hello").unwrap();
uwriteln!(&mut s, "World",).unwrap();
assert_eq!(s, "Hello\nWorld\n");
}
#[test]
fn formatter_uwrite() {
#[derive(uDebug)]
struct X;
struct Y;
impl uDebug for Y {
fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
where
W: uWrite + ?Sized,
{
uwrite!(f, "{:?}", X)
}
}
assert_eq!(uformat!("{:?}", Y).unwrap(), "X")
}
#[test]
fn generic() {
#[derive(uDebug, Debug)]
struct X<T>(T);
cmp!("{:?}", X(0));
#[derive(uDebug, Debug)]
enum Y<T> {
Z(T),
}
cmp!("{:?}", Y::Z(0));
}
#[allow(dead_code)]
fn static_lifetime(x: &'static mut u32) {
fn foo(x: &'static mut u32) -> *mut u32 {
x as *mut u32
}
uwrite!(&mut String::new(), "{:?}", foo(x)).ok();
}
#[test]
fn dst() {
struct Cursor<B>
where
B: ?Sized,
{
pos: usize,
buffer: B,
}
impl<B> Cursor<B> {
fn new(buffer: B) -> Self {
Cursor { pos: 0, buffer }
}
}
impl uWrite for Cursor<[u8]> {
type Error = Infallible;
fn write_str(&mut self, s: &str) -> Result<(), Infallible> {
let bytes = s.as_bytes();
let len = bytes.len();
let start = self.pos;
if let Some(buffer) = self.buffer.get_mut(start..start + len) {
buffer.copy_from_slice(bytes);
self.pos += len;
}
Ok(())
}
}
let mut cursor = Cursor::new([0; 256]);
let cursor: &mut Cursor<[u8]> = &mut cursor;
uwrite!(cursor, "The answer is {}", 42).ok();
let msg = b"The answer is 42";
assert_eq!(&cursor.buffer[..msg.len()], msg);
}
#[test]
fn hex() {
cmp!("{:x}", 771u32);
cmp!("{:x}", -10000);
cmp!("{:4x}", 33);
cmp!("{:4x}", 89001);
cmp!("{:04x}", 33);
cmp!("{:#03x}", 33);
cmp!("{:#09x}", 33);
cmp!("{:#x}", 71);
cmp!("{:x}", i8::min_value());
cmp!("{:x}", i8::max_value());
cmp!("{:x}", i16::min_value());
cmp!("{:x}", i16::max_value());
cmp!("{:x}", i32::min_value());
cmp!("{:x}", i32::max_value());
cmp!("{:x}", i64::min_value());
cmp!("{:x}", i64::max_value());
cmp!("{:x}", i128::min_value());
cmp!("{:x}", i128::max_value());
cmp!("{:x}", isize::min_value());
cmp!("{:x}", isize::max_value());
}