use std::os::raw::c_void;
use std::ptr;
pub unsafe trait Data {
fn newt_to_ptr(&self) -> *const c_void;
fn newt_from_ptr(ptr: *const c_void) -> Self;
}
unsafe impl Data for () {
fn newt_to_ptr(&self) -> *const c_void {
ptr::null()
}
fn newt_from_ptr(_ptr: *const c_void) -> Self { }
}
unsafe impl Data for char {
fn newt_to_ptr(&self) -> *const c_void {
if !self.is_ascii() {
panic!("UTF-8 characters are not supported.");
}
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as u8 as Self
}
}
unsafe impl Data for i8 {
fn newt_to_ptr(&self) -> *const c_void {
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize as Self
}
}
unsafe impl Data for u8 {
fn newt_to_ptr(&self) -> *const c_void {
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize as Self
}
}
unsafe impl Data for isize {
fn newt_to_ptr(&self) -> *const c_void {
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize as Self
}
}
unsafe impl Data for usize {
fn newt_to_ptr(&self) -> *const c_void {
*self as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize
}
}
unsafe impl Data for i16 {
fn newt_to_ptr(&self) -> *const c_void {
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize as Self
}
}
unsafe impl Data for u16 {
fn newt_to_ptr(&self) -> *const c_void {
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize as Self
}
}
#[cfg(all(nightly, feature = "f16"))]
unsafe impl Data for f16 {
fn newt_to_ptr(&self) -> *const c_void {
self.to_bits() as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
Self::from_bits(ptr as u16)
}
}
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
unsafe impl Data for i32 {
fn newt_to_ptr(&self) -> *const c_void {
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize as Self
}
}
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
unsafe impl Data for u32 {
fn newt_to_ptr(&self) -> *const c_void {
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize as Self
}
}
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
unsafe impl Data for f32 {
fn newt_to_ptr(&self) -> *const c_void {
self.to_bits() as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
Self::from_bits(ptr as u32)
}
}
#[cfg(target_pointer_width = "64")]
unsafe impl Data for i64 {
fn newt_to_ptr(&self) -> *const c_void {
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize as Self
}
}
#[cfg(target_pointer_width = "64")]
unsafe impl Data for u64 {
fn newt_to_ptr(&self) -> *const c_void {
*self as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
ptr as usize as Self
}
}
#[cfg(target_pointer_width = "64")]
unsafe impl Data for f64 {
fn newt_to_ptr(&self) -> *const c_void {
self.to_bits() as usize as *const c_void
}
fn newt_from_ptr(ptr: *const c_void) -> Self {
Self::from_bits(ptr as u64)
}
}
#[test]
fn char_data_should_accept_ascii() {
let c = '0';
let _ptr = c.newt_to_ptr();
}
#[test]
#[should_panic(expected = "UTF-8 characters are not supported.")]
fn char_data_should_not_accept_utf8() {
let c = '\u{1F603}';
let _ptr = c.newt_to_ptr();
}
#[test]
fn isize_data_should_cast_correctly() {
let i: isize = isize::MIN / 3;
let ptr = i.newt_to_ptr();
let i = isize::newt_from_ptr(ptr);
assert!(i == (isize::MIN / 3));
}
#[test]
fn usize_data_should_cast_correctly() {
let i: usize = usize::MAX / 3;
let ptr = i.newt_to_ptr();
let i = usize::newt_from_ptr(ptr);
assert!(i == (usize::MAX / 3));
}
#[test]
fn i8_data_should_cast_correctly() {
let i: i8 = i8::MIN / 3;
let ptr = i.newt_to_ptr();
let i = i8::newt_from_ptr(ptr);
assert!(i == (i8::MIN / 3));
}
#[test]
fn u8_data_should_cast_correctly() {
let i: u8 = u8::MAX / 3;
let ptr = i.newt_to_ptr();
let i = u8::newt_from_ptr(ptr);
assert!(i == (u8::MAX / 3));
}
#[test]
fn i16_data_should_cast_correctly() {
let i: i16 = i16::MIN / 3;
let ptr = i.newt_to_ptr();
let i = i16::newt_from_ptr(ptr);
assert!(i == (i16::MIN / 3));
}
#[test]
#[cfg(all(nightly,feature = "f16"))]
fn f16_data_should_cast_correctly() {
let f: f16 = f16::MIN / 3.0;
let ptr = f.newt_to_ptr();
let f = f16::newt_from_ptr(ptr);
assert!(f == (f16::MIN / 3.0));
}
#[test]
fn u16_data_should_cast_correctly() {
let i: u16 = u16::MAX / 3;
let ptr = i.newt_to_ptr();
let i = u16::newt_from_ptr(ptr);
assert!(i == (u16::MAX / 3));
}
#[test]
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
fn i32_data_should_cast_correctly() {
let i: i32 = i32::MIN / 3;
let ptr = i.newt_to_ptr();
let i = i32::newt_from_ptr(ptr);
assert!(i == (i32::MIN / 3));
}
#[test]
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
fn u32_data_should_cast_correctly() {
let i: u32 = u32::MAX / 3;
let ptr = i.newt_to_ptr();
let i = u32::newt_from_ptr(ptr);
assert!(i == (u32::MAX / 3));
}
#[test]
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
fn f32_data_should_cast_correctly() {
let f: f32 = f32::MIN / 3.0;
let ptr = f.newt_to_ptr();
let f = f32::newt_from_ptr(ptr);
assert!(f == (f32::MIN / 3.0));
}
#[test]
#[cfg(target_pointer_width = "64")]
fn i64_data_should_cast_correctly() {
let i: i64 = i64::MIN / 3;
let ptr = i.newt_to_ptr();
let i = i64::newt_from_ptr(ptr);
assert!(i == (i64::MIN / 3));
}
#[test]
#[cfg(target_pointer_width = "64")]
fn u64_data_should_cast_correctly() {
let i: u64 = u64::MAX / 3;
let ptr = i.newt_to_ptr();
let i = u64::newt_from_ptr(ptr);
assert!(i == (u64::MAX / 3));
}
#[test]
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
fn f64_data_should_cast_correctly() {
let f: f64 = f64::MIN / 3.0;
let ptr = f.newt_to_ptr();
let f = f64::newt_from_ptr(ptr);
assert!(f == (f64::MIN / 3.0));
}