Skip to content

Instantly share code, notes, and snippets.

@thomcc
Created August 30, 2020 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomcc/bbb758420337d89eafa0e60c34b387b0 to your computer and use it in GitHub Desktop.
Save thomcc/bbb758420337d89eafa0e60c34b387b0 to your computer and use it in GitHub Desktop.
evcxr prelude
pub use std::{mem::*, ptr::NonNull, char};
pub use std::marker::PhantomData;
pub trait EvcxrNumFmtHelp {
fn hex(self) -> HexF;
fn bin(self) -> BinF;
}
impl<I: Into<i128>> EvcxrNumFmtHelp for I {
fn hex(self) -> HexF { HexF(self.into() as u128, core::mem::size_of::<I>()) }
fn bin(self) -> BinF { BinF(self.into() as u128, core::mem::size_of::<I>()) }
}
pub trait EvcxrNumFmtHelpHack {
fn hexx(&self) -> HexF;
fn binx(&self) -> BinF;
}
impl EvcxrNumFmtHelpHack for u128 {
fn hexx(&self) -> HexF { HexF(*self, 16) }
fn binx(&self) -> BinF { BinF(*self, 16) }
}
impl EvcxrNumFmtHelpHack for f64 {
fn hexx(&self) -> HexF { HexF(self.to_bits() as u128, 8) }
fn binx(&self) -> BinF { BinF(self.to_bits() as u128, 8) }
}
impl EvcxrNumFmtHelpHack for f32 {
fn hexx(&self) -> HexF { HexF(self.to_bits() as u128, 4) }
fn binx(&self) -> BinF { BinF(self.to_bits() as u128, 4) }
}
impl EvcxrNumFmtHelpHack for char {
fn hexx(&self) -> HexF { (*self as u32).hex() }
fn binx(&self) -> BinF { (*self as u32).bin() }
}
pub struct BinF(pub u128, pub usize);
impl core::fmt::Debug for BinF {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("0b")?;
if self.1 == 1 || (self.1 == 4 && self.0 <= 0xff) {
return write!(f, "{:04b}_{:04b}", (self.0 as u8) >> 4, (self.0 as u8) & 0xf);
}
if (self.1 == 4 && self.0 <= 0xffff) {
return write!(f, "{:04b}_{:04b}_{:04b}_{:04b}",
((self.0 as u16) >> 12) & 0xf,
((self.0 as u16) >> 8) & 0xf,
((self.0 as u16) >> 4) & 0xf,
(self.0 as u16) & 0xf
);
}
for i in (0..self.1).rev() {
if i != self.1 - 1 {
f.write_str("_")?;
}
write!(f, "{:08b}", ((self.0 >> (i * 8)) & 0xff))?;
}
Ok(())
}
}
pub struct HexF(pub u128, pub usize);
impl core::fmt::Debug for HexF {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("0x")?;
if self.1 == 1 || (self.1 == 4 && self.0 <= 0xff) {
return write!(f, "{:02x}", self.0 as u8);
}
let fields = (self.1 + 1) / 2;
for i in (0..fields).rev() {
if i != fields - 1 {
f.write_str("_")?;
}
write!(f, "{:04x}", ((self.0 >> (i * 16)) & 0xffff))?;
}
Ok(())
}
}
pub struct EvcxrDbgBytes<'a>(&'a [u8], bool, bool);
impl<'a> core::fmt::Debug for EvcxrDbgBytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
fn hexb(f: &mut core::fmt::Formatter, b: u8, bslash: bool) -> core::fmt::Result {
if bslash { f.write_str("\\x")?; }
write!(f, "{:02X}", b)
}
f.write_str("b\"")?;
let alt = f.alternate();
let mut i = 0;
while i < self.0.len() {
let b = self.0[i];
if self.2 {
hexb(f, b, true)?;
} else if b.is_ascii_graphic() || b == b' ' {
// f.write_str(core::str::from_utf8(&[b]).unwrap())?;
core::fmt::Display::fmt(&(b as char), f)?;
} else if b.is_ascii_whitespace() || b == b'"' || b == b'\\' || b == b'\'' {
core::fmt::Debug::fmt(&(b as char), f)?;
} else if b.is_ascii() {
hexb(f, b, true)?;
} else if !alt {
// let s = self.0.get(i..(i+2)).and_then(|f| core::str::from_utf8(f).ok())
// .or_else(|| self.0.get(i..(i+3)).and_then(|f| core::str::from_utf8(f).ok()))
// .or_else(|| self.0.get(i..(i+4)).and_then(|f| core::str::from_utf8(f).ok()));
if let Ok(s) = self.0.chqs(i) {
if self.1 || s == "\u{fffd}" {
core::fmt::Debug::fmt(s, f)?;
// write!(f, "{}", s.escape_debug())?;
} else {
f.write_str("\\u{")?;
for (i, b) in s.bytes().enumerate() {
if i > 0 { f.write_str(" ")?; }
hexb(f, b, false)?;
// write!(f, "{:02X}", b)?;
}
f.write_str("}")?;
}
i += s.len() - 1;
} else {
hexb(f, b, true)?;
}
} else {
hexb(f, b, true)?;
}
i += 1;
}
f.write_str("\"")
}
}
pub trait EvcxrBytesExt {
fn b(&self) -> &[u8];
fn to_str(&self) -> Result<&str, core::str::Utf8Error> { core::str::from_utf8(self.b()) }
fn to_str_lossy(&self) -> String { String::from_utf8_lossy(self.b()).to_string() }
fn lossy(&self) -> String { self.to_str_lossy() }
fn bstrx(&self) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(self.b(), false, true) }
fn bstr(&self) -> EvcxrDbgBytes<'_> { self.dbg_bytes(false, false) }
fn bstru(&self) -> EvcxrDbgBytes<'_> { self.dbg_bytes(true, false) }
fn hexs(&self) -> EvcxrDbgBytes<'_> { self.bstrx() }
fn dbg_bytes(&self, unicode: bool, allhex: bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(self.b(), unicode, allhex) }
fn ch0(&self) -> char { self.ch(0) }
fn ch(&self, i: usize) -> char {
match self.chq(i) {
Ok(v) => v,
Err("out of bounds") => '\0',
_ => '\u{fffd}'
}
}
fn chqs(&self, i: usize) -> Result<&'_ str, &'static str> {
let b = self.b();
if i >= b.len() { return Err("out of bounds") }
for l in 1..=4 {
if let Some(s) = b.get(i..(i+l)).and_then(|bs| core::str::from_utf8(bs).ok()) {
return Ok(s);
}
}
Err("invalid utf8")
}
fn chq(&self, i: usize) -> Result<char, &'static str> {
self.chqs(i).and_then(|s| s.chars().next().ok_or("bug??"))
}
}
impl<T: AsRef<[u8]> + ?Sized> EvcxrBytesExt for T {
fn b(&self) -> &[u8] { self.as_ref() }
}
/*
impl EvcxrBytesExt for str { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(self.as_bytes(), b, false) } }
impl EvcxrBytesExt for String { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(self.as_bytes(), b, false) } }
impl EvcxrBytesExt for [u8] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(self, b, true) } }
impl EvcxrBytesExt for Vec<u8> { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;0] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;1] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;2] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;3] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;4] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;5] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;6] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;7] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;8] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;9] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;10] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;11] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;12] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;13] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;14] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;16] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;17] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;18] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;19] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;20] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;21] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;22] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;23] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;24] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;25] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;26] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;27] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;28] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;29] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;30] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;31] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }
impl EvcxrBytesExt for [u8;32] { fn bstrv(&self,b:bool) -> EvcxrDbgBytes<'_> { EvcxrDbgBytes(&self[..], b, true) } }*/
pub trait U32Ext {
fn to_char(&self) -> Result<char, u32>;
fn ch(&self) -> char {self.to_char().unwrap_or('\u{fffd}')}
}
impl U32Ext for u32 {
fn to_char(&self) -> Result<char, u32> { core::char::from_u32(*self).ok_or(*self) }
}
pub trait CharExt:Copy {
fn utf8b(self) -> DebugS;
fn utf8x(self) -> DebugS;
fn to_utf8(self) -> String;
fn hex8(self) -> DebugS { self.utf8x() }
fn bin8(self) -> DebugS { self.utf8b() }
}
// impl CharExt for u32 {
// fn to_utf8(self) -> String { self.ch().to_utf8() }
// fn utf8b(self) -> DebugS { self.ch().utf8b() }
// fn utf8x(self) -> DebugS { self.ch().utf8x() }
// }
impl CharExt for char {
fn to_utf8(self) -> String { self.encode_utf8(&mut [0u8; 4]).to_owned() }
fn utf8b(self) -> DebugS { DebugS(format!("{:?}", self.encode_utf8(&mut [0u8; 4]).bytes().map(|b| b.bin()).collect::<Vec<_>>())) }
fn utf8x(self) -> DebugS { DebugS(format!("{:?}", self.encode_utf8(&mut [0u8; 4]).bytes().map(|b| b.hex()).collect::<Vec<_>>())) }
}
pub struct DebugS(pub String);
impl core::fmt::Debug for DebugS {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment