win64 0.0.1

An opinionated modernization of the Win32 windowing library
use std::ptr::NonNull;

use windows::{
  core::{HSTRING, PCWSTR},
  Win32::{Foundation::HINSTANCE, System::LibraryLoader::GetModuleHandleW},
};

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Handle(Option<NonNull<usize>>);

impl Handle {
  pub fn as_ptr(&self) -> *mut core::ffi::c_void {
    self
      .0
      .map_or(core::ptr::null_mut(), |ptr| ptr.cast::<core::ffi::c_void>().as_ptr())
  }

  pub fn from_raw(ptr: *mut core::ffi::c_void) -> Self {
    Self(NonNull::new(ptr.cast()))
  }

  pub fn is_null(&self) -> bool {
    self.0.is_none()
  }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Instance(Handle);

impl Default for Instance {
  fn default() -> Self {
    Self::get_exe()
  }
}

impl Instance {
  #[inline]
  pub fn get_exe() -> Self {
    Self::get(None::<&str>).unwrap() // shouldn't fail, right?
  }

  pub fn get(module: Option<impl Into<String>>) -> Result<Self, windows::core::Error> {
    unsafe {
      GetModuleHandleW(
        module
          .map(Into::into)
          .map(HSTRING::from)
          .map_or_else(PCWSTR::null, |n| PCWSTR(n.as_ptr())),
      )
    }
    .map(|value| HINSTANCE(value.0).into())
  }

  /// # Safety
  /// 
  /// Raw pointers are scary
  pub unsafe fn as_ptr(&self) -> *mut core::ffi::c_void {
    self.0.as_ptr()
  }

  pub fn is_null(&self) -> bool {
    self.0.is_null()
  }
}

impl From<Instance> for HINSTANCE {
  fn from(value: Instance) -> Self {
    Self(value.0.as_ptr())
  }
}

impl From<HINSTANCE> for Instance {
  fn from(value: HINSTANCE) -> Self {
    Self(Handle::from_raw(value.0))
  }
}