heapbuf 0.1.3

Fixed size heap buffer with optional custom alignment, ref counting and custom destructor logic.
Documentation
use std::io::Read;
use std::sync::atomic::Ordering;
use std::thread;

use lazy_static::lazy_static;

use heapbuf::*;

#[test]
fn test_alloc() -> std::io::Result<()> {
    let mut buf = HBuf::try_allocate_aligned_zeroed(512,4096)?;
    assert_eq!(0, buf.as_ptr().align_offset(4096));
    println!("{}", buf[0]);
    buf[0] = 0x44;
    println!("{}", buf[0]);
    let u = unsafe { buf.as_mut_slice_generic::<u32>().unwrap() };
    assert_eq!(u.len(), 512/4);
    assert_eq!(u[0], 0x44);
    buf[1] = 0x32;
    let u = unsafe { buf.as_mut_slice_generic::<u32>().unwrap() };

    assert_eq!(u[0], 0x3244);
    assert_eq!(8usize/3usize, 2usize);

    #[cfg(feature = "f16_support")]
    {
        let f = unsafe { buf.as_mut_slice_generic::<half::f16>().unwrap() };
        assert_eq!("0.19580078", format!("{}", f[0]));
    }

    drop(buf);
    return Ok(());
}

lazy_static! {
    static ref THE_BUF: HBuf = HBuf::allocate(512);
}

#[test]
fn test_mt() -> std::io::Result<()> {
    let t = thread::spawn(|| {
        let mut x = vec![0u8; 16];
        THE_BUF.clone().read_exact(x.as_mut_slice()).expect("Failed");

    });

    t.join().expect("Failed");
    return Ok(());
}

#[cfg(feature = "uintx_support")]
#[test]
fn test_unaligned() -> std::io::Result<()> {
    let mut buf = HBuf::try_allocate_aligned_zeroed(512, 4)?;
    buf[0] = 0x24;
    buf[1] = 0x23;
    buf[2] = 0x22;
    buf[3] = 0x44;
    buf[4] = 0x25;

    let x = buf.split(1, buf.capacity()-1);
    let z = x.get_u32(0);
    assert_eq!(z, 0x25442223u32.to_le());
    assert!(x.as_slice_u32().is_none());
    assert!(x.as_slice_u24().is_some());
    let n = x.as_slice_u24().unwrap()[0];
    assert_eq!(n, uintx::u24::from_ne_bytes([0x23,0x22, 0x44]));

    return Ok(());
}

#[test]
fn test_atomic_get() -> std::io::Result<()> {
    let buf = HBuf::try_allocate_zeroed(513)?;
    let n = buf.compare_and_exchange_u8(0, 0,4, Ordering::SeqCst, Ordering::SeqCst).expect("bla");
    assert_eq!(n, 0);
    assert_eq!(4, buf.get_u8(0));
    return Ok(());
}



#[test]
#[cfg(target_pointer_width = "64")]
fn test_display() -> std::io::Result<()> {
    let mut buf = HBuf::try_allocate_zeroed(513)?;

    buf[0] = 'H'.try_into().unwrap();
    buf[1] = 'a'.try_into().unwrap();
    buf[2] = 'l'.try_into().unwrap();
    buf[3] = 'l'.try_into().unwrap();
    buf[4] = 'o'.try_into().unwrap();

    buf[47] = 'W'.try_into().unwrap();
    buf[48] = 'e'.try_into().unwrap();
    buf[49] = 'l'.try_into().unwrap();
    buf[50] = 't'.try_into().unwrap();


    buf[66] = '@'.try_into().unwrap();
    buf[67] = '\n'.try_into().unwrap();
    buf[67] = '\t'.try_into().unwrap();
    buf[511] = 'Z'.try_into().unwrap();

    let mut str = format!("{}", buf);
    unsafe {
        for x in 0..buf.capacity() {
            str = str.replace(format!("0x{:016x}", buf.as_ptr().add(x) as usize).as_str(), format!("0x{:016x}", x).as_str());

        }
        str = str.replace(format!("{:p}", buf.as_ptr()).as_str(), "0x0");
        str = str.replace(format!("{:p}", buf.as_ptr().add(buf.capacity())).as_str(), format!("0x{:x}", buf.capacity()).as_str());
    }

    let expected = "=============================================================================
Address: 0x0-0x201
Capacity: 513
Limit: 513
Position: 0
Has destructor: true
Reference count: 1
=============================================================================
0x0000000000000000: 4861 6c6c 6f00 0000 0000 0000 0000 0000  Hallo...........
0x0000000000000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000020: 0000 0000 0000 0000 0000 0000 0000 0057  ...............W
0x0000000000000030: 656c 7400 0000 0000 0000 0000 0000 0000  elt.............
0x0000000000000040: 0000 4009 0000 0000 0000 0000 0000 0000  ..@.............
0x0000000000000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000000f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000110: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000120: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000130: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000140: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000150: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000160: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000170: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000180: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0000000000000190: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000001a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000001b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000001c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000000000001f0: 0000 0000 0000 0000 0000 0000 0000 005a  ...............Z
0x0000000000000200: 00                                       .               \
\n=============================================================================";
//Curse you rust rover remover of trailing whitespaces

    assert_eq!(str, expected);

    assert_eq!(format!("{:X}", buf),
               "48616C6C6F00000000000000000000000000000000000000000000000000000000000000000000000000000000000057656C74000000000000000000000000000000400900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005A00");

    assert_eq!(format!("{:x}", buf),
               "48616C6C6F00000000000000000000000000000000000000000000000000000000000000000000000000000000000057656C74000000000000000000000000000000400900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005A00"
                .to_ascii_lowercase());

    return Ok(());
}