use ::core::fmt::Display;
use ::with_locals::with;
#[with('local)]
fn hex (n: u32) -> &'local dyn Display
{
&format_args!("{:#x}", n)
}
no_run! {
fn with_hex<R, F> (n: u32, f: F) -> R
where
F : for<'local> FnOnce(&'local dyn Display) -> R,
{
f(&format_args!("{:#x}", n))
}
with_hex(66, |s| {
println!("{}", s);
})
with_hex(1, |one| {
with_hex(2, |two| {
with_hex(3, |three| {
})
})
})
let one = hex(1);
let two = hex(2);
let three = hex(3);
#[with] let one = hex(1);
#[with] let two = hex(2);
#[with] let three = hex(3);
let one: &'local _ = hex(1);
let two: &'local _ = hex(2);
let three: &'local _ = hex(3);
}
#[with('local)]
fn hex_example ()
{
let s: String = {
println!("Hello, World!");
let s_hex: &'local _ = hex(66);
println!("s_hex = {}", s_hex);
let s = s_hex.to_string();
assert_eq!(s, "0x42");
s
};
assert_eq!(s, "0x42");
}
no_run! {
let s: String = {
println!("Hello, World!");
with_hex(66, |s_hex| {
println!("s_hex = {}", s_hex);
let s = s_hex.to_string();
assert_eq!(s, "0x42");
s
})
};
assert_eq!(s, "0x42");
}
trait ToStr {
#[with('local)]
fn to_str (self: &'_ Self) -> &'local str
;
}
impl<T : ToStr> Display for Displayable<T> {
#[with('local)] fn fmt (self: &'_ Self, fmt: &'_ mut ::core::fmt::Formatter<'_>)
-> ::core::fmt::Result
{
let s: &'local str = self.0.to_str();
fmt.write_str(s)
}
}
struct Displayable<T : ToStr>(T);
impl ToStr for u32 {
#[with('local)] fn to_str (self: &'_ u32) -> &'local str
{
let mut x = *self;
if x == 0 {
return "0";
}
let mut buf = [b' '; 1 + 3 + 3 + 3]; let mut cursor = &mut buf[..];
while x > 0 {
let (last, cursor_) = cursor.split_last_mut().unwrap();
cursor = cursor_;
*last = b'0' + (x % 10) as u8;
x /= 10;
}
let len = cursor.len();
::core::str::from_utf8(&buf[len ..]) .unwrap()
}
}
#[with('local)]
fn main ()
{
hex_example();
let n: &'local str = ::core::u32::MAX.to_str();
dbg!(n);
assert_eq!(n.parse(), Ok(::core::u32::MAX));
romans();
}
#[with('local)]
fn roman (mut n: u8) -> &'local str
{
if n == 0 {
panic!("Vade retro!");
}
let mut buf = [b' '; 1 + 4 + 4]; let mut start = buf.len();
let mut prepend = |b| {
start = start.checked_sub(1).expect("Out of capacity!");
buf[start] = b;
};
const DIGITS: [u8; 7] = *b"IVXLCDM";
(0 ..= 2).for_each(|shift| {
#[allow(nonstandard_style)]
let (I, V, X) = (
DIGITS[2 * shift],
DIGITS[2 * shift + 1],
DIGITS[2 * shift + 2],
);
match n % 10 {
| i @ 0 ..= 3 => {
(0 .. i).for_each(|_| prepend(I));
},
| 4 => {
prepend(V);
prepend(I);
},
| i @ 5 ..= 8 => {
(0 .. (i - 5)).for_each(|_| prepend(I));
prepend(V);
},
| 9 => {
prepend(X);
prepend(I);
},
| _ => unreachable!(),
}
n /= 10;
});
::core::str::from_utf8(&buf[start ..]) .unwrap()
}
#[with('local)]
fn romans ()
{
for n in 1 ..= ::core::u8::MAX {
let s: &'local str = roman(n);
println!("{:3} = {}", n, s);
}
}
#[macro_export] macro_rules! no_run {($($tt:tt)*) => ()}