use std::{
  ffi::{c_char, c_void, CStr, CString},
  fs, io,
  path::Path,
  ptr::{self, NonNull},
  sync::LockResult,
};

#[cfg(feature = "dialog")]
use crate::dialog::*;
use crate::{
  http::status::StatusCode, system::get_original_dir, CResult, Error, Result, WebResult,
};
use chrono::{DateTime, Datelike, Local, Timelike};
use lazy_static::lazy_static;
use regex::Regex;
use serde::{de::DeserializeOwned, Serialize};
use serde_json::Value;

lazy_static! {
  static ref REGEX_FORMAT_PATTERN: Regex = Regex::new(r"\{([a-zA-Z0-9_]+)\}").unwrap();
}
#[cfg(target_os = "windows")]
lazy_static! {
  static ref REGEX_ENV_PATTERN: Regex = Regex::new(r"\%([a-zA-Z0-9_]+)\%").unwrap();
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
lazy_static! {
  static ref REGEX_ENV_PATTERN: Regex = Regex::new(r"\$\{([a-zA-Z0-9_]+)\}").unwrap();
}
#[cfg(not(any(target_os = "linux", target_os = "windows", target_os = "macos")))]
lazy_static! {
  static ref REGEX_ENV_PATTERN: Regex = Regex::new(r"\$([a-zA-Z0-9_]+)").unwrap();
}

/// 剔除空字符
pub trait ToStringWithoutNulls {
  /// 剔除空字符
  fn to_string_without_nulls(&self) -> String;
}

impl ToStringWithoutNulls for [u8] {
  fn to_string_without_nulls(&self) -> String {
    let mut result = String::with_capacity(self.len());
    for &byte in self {
      if byte != 0 {
        result.push(byte as char);
      }
    }
    result
  }
}

impl ToStringWithoutNulls for Vec<u8> {
  fn to_string_without_nulls(&self) -> String {
    let mut result = String::with_capacity(self.len());
    for &byte in self {
      if byte != 0 {
        result.push(byte as char);
      }
    }
    result
  }
}

/// 转换成指针
pub fn any_to_c_ptr2<T>(value: &T) -> *const c_void {
  value as *const T as *const c_void
}
/// 指针转换
pub unsafe fn c_ptr_to_any2<T>(pointer: *const c_void) -> T {
  ptr::read(pointer as *const T)
}
/// 安全地获取<Box<T>>实例的*mut c_void指针
pub fn any_to_c_ptr<T>(boxed_value: Box<T>) -> *const c_void {
  Box::into_raw(boxed_value) as *const T as *const c_void
}
/// 安全地还原*c_void指针为<Box<T>>实例
pub unsafe fn c_ptr_to_any<T>(void_ptr: *const c_void) -> Option<Box<T>> {
  // 使用NonNull来避免空指针
  let non_null_ptr = NonNull::new(void_ptr as *mut T);
  // 安全地解引用NonNull指针并创建一个新的Box
  non_null_ptr.map(|ptr| Box::from_raw(ptr.as_ptr() as *mut T))
}
/// 安全地获取<Box<T>>实例的*mut c_void指针
pub fn any_to_c_mut_ptr<T: Sized>(boxed_value: Box<T>) -> *mut c_void {
  Box::into_raw(boxed_value) as *mut T as *mut c_void
}
/// 安全地还原*c_void指针为<Box<T>>实例
pub unsafe fn c_mut_ptr_to_any<T: Sized>(void_ptr: *mut c_void) -> Option<Box<T>> {
  // 使用NonNull来避免空指针
  let non_null_ptr = NonNull::new(void_ptr as *mut T);
  // 安全地解引用NonNull指针并创建一个新的Box
  non_null_ptr.map(|ptr| Box::from_raw(ptr.as_ptr() as *mut T))
}

/// 针对C/C++
pub trait AutoParse {
  /// 转CsString
  fn to_cstring(&self) -> Result<CString>;
  /// 转 *const c_char
  fn to_c_char(&self) -> *const std::ffi::c_char;
}
impl<S: Serialize + AsRef<str>> AutoParse for S {
  fn to_cstring(&self) -> Result<CString> {
    Ok(CString::new(self.as_ref())?)
  }

  fn to_c_char(&self) -> *const std::ffi::c_char {
    self.to_cstring().def().into_raw()
  }
}
impl AutoParse for Path {
  fn to_cstring(&self) -> Result<CString> {
    Ok(CString::new(
      self
        .to_str()
        .ok_or(Error::Str("AutoParse<to_cstring<解析>>".into()))?,
    )?)
  }

  fn to_c_char(&self) -> *const std::ffi::c_char {
    self.to_cstring().def().into_raw()
  }
}
/// 针对C/C++
pub unsafe trait CAutoParse {
  /// C转CsString
  unsafe fn c_to_cstring(&self) -> CString;
  /// C转String
  unsafe fn c_to_string(&self) -> String;
  /// 安全地获取<Box<T>>实例的*c_void指针
  fn c_to_ptr(self) -> *const c_void;
  /// 安全地获取<Box<T>>实例的*mut c_void指针
  fn c_to_mut_ptr(self) -> *mut c_void;
  /// 安全地还原*c_void指针为<Box<T>>实例
  unsafe fn c_to_any<T>(self) -> Option<Box<T>>;
}
unsafe impl CAutoParse for *const c_char {
  unsafe fn c_to_cstring(&self) -> CString {
    unsafe { CStr::from_ptr(*self).into() }
  }
  unsafe fn c_to_string(&self) -> String {
    self.c_to_cstring().into_string().def()
  }
  unsafe fn c_to_any<T: Sized>(self) -> Option<Box<T>> {
    c_ptr_to_any(self.c_to_ptr())
  }
  fn c_to_ptr(self) -> *const c_void {
    any_to_c_ptr(Box::new(self))
  }
  fn c_to_mut_ptr(self) -> *mut c_void {
    any_to_c_mut_ptr(Box::new(self))
  }
}
unsafe impl CAutoParse for *mut c_char {
  unsafe fn c_to_cstring(&self) -> CString {
    CString::from_raw(*self)
  }
  unsafe fn c_to_string(&self) -> String {
    self.c_to_cstring().into_string().def()
  }
  fn c_to_ptr(self) -> *const c_void {
    any_to_c_ptr(Box::new(self))
  }
  fn c_to_mut_ptr(self) -> *mut c_void {
    any_to_c_mut_ptr(Box::new(self))
  }
  unsafe fn c_to_any<T: Sized>(self) -> Option<Box<T>> {
    c_ptr_to_any(self.c_to_ptr())
  }
}

unsafe impl CAutoParse for *const c_void {
  unsafe fn c_to_cstring(&self) -> CString {
    panic!("不支持c_void")
  }
  unsafe fn c_to_string(&self) -> String {
    panic!("不支持c_void")
  }
  fn c_to_ptr(self) -> *const c_void {
    self
  }
  fn c_to_mut_ptr(self) -> *mut c_void {
    self as *mut c_void
  }
  unsafe fn c_to_any<T>(self) -> Option<Box<T>> {
    c_ptr_to_any(self)
  }
}
unsafe impl CAutoParse for *mut c_void {
  unsafe fn c_to_cstring(&self) -> CString {
    panic!("不支持c_void")
  }
  unsafe fn c_to_string(&self) -> String {
    panic!("不支持c_void")
  }
  fn c_to_ptr(self) -> *const c_void {
    self as *const c_void
  }
  fn c_to_mut_ptr(self) -> *mut c_void {
    self
  }
  unsafe fn c_to_any<T>(self) -> Option<Box<T>> {
    c_ptr_to_any(self.c_to_mut_ptr())
  }
}

/// 解析特殊类型的错误
pub trait ParseResult<T> {
  /// 解析返回Result
  fn res(self) -> Result<T>;
  /// 解析Result转CResult
  fn res_c(self) -> CResult<T>;
  /// 解包并用dialog和panic
  fn un(self, _title: &str, add: &str) -> T;
}
/// 解析WebResult
pub trait ParseWebResult<T: Serialize> {
  /// 解析WebResult
  fn res_web(&self) -> Result<WebResult<String>>;
}
impl<T: Serialize> ParseWebResult<T> for Result<T> {
  fn res_web(&self) -> Result<WebResult<String>> {
    Result::Ok(match self {
      Result::Ok(data) => WebResult {
        code: StatusCode::OK.into(),
        msg: "OK".into(),
        data: serde_json::to_string(&data)?,
      },
      Result::Err(e) => WebResult {
        code: e.status_code().into(),
        msg: e.to_string().into(),
        data: String::new(),
      },
    })
  }
}

/// 解析默认
pub trait ParseResultDefault<T> {
  /// 解析返回Default
  fn def(self) -> T;
}
impl<T: Default> ParseResultDefault<T> for LockResult<T> {
  fn def(self) -> T {
    self.unwrap_or_default()
  }
}
impl<T: Default> ParseResultDefault<T> for Result<T> {
  fn def(self) -> T {
    self.unwrap_or_default()
  }
}
impl<T: Default> ParseResultDefault<T> for CResult<T> {
  fn def(self) -> T {
    self.res().unwrap_or_default()
  }
}
impl<T: Default> ParseResultDefault<T> for std::result::Result<T, std::io::Error> {
  fn def(self) -> T {
    self.unwrap_or_default()
  }
}
impl<T: Default> ParseResultDefault<T> for std::result::Result<T, std::ffi::IntoStringError> {
  fn def(self) -> T {
    self.unwrap_or_default()
  }
}
impl<T: Default> ParseResultDefault<T> for std::result::Result<T, std::env::VarError> {
  fn def(self) -> T {
    self.unwrap_or_default()
  }
}
impl<T: Default> ParseResultDefault<T> for Option<T> {
  fn def(self) -> T {
    self.unwrap_or_default()
  }
}

impl<T> ParseResult<T> for LockResult<T> {
  fn res(self) -> Result<T> {
    match self {
      Self::Ok(x) => Ok(x),
      Self::Err(e) => Err(Error::unprocessable_entity([(
        "LockResult<T,PoisonError<T>>",
        e.to_string(),
      )])),
    }
  }
  fn res_c(self) -> CResult<T> {
    self.res().into()
  }
  fn un(self, _title: &str, add: &str) -> T {
    match self {
      Self::Ok(x) => x,
      Self::Err(e) => {
        let ref msg = format!("{e};{add}");
        #[cfg(feature = "dialog")]
        dialog_err_block(_title, msg);
        panic!("{}", msg)
      }
    }
  }
}
impl<T> ParseResult<T> for Result<T> {
  fn res(self) -> Result<T> {
    self
  }
  fn res_c(self) -> CResult<T> {
    self.into()
  }
  fn un(self, _title: &str, add: &str) -> T {
    match self {
      Self::Ok(x) => x,
      Self::Err(e) => {
        let ref msg = format!("{e};{add}");
        #[cfg(feature = "dialog")]
        dialog_err_block(_title, msg);
        panic!("{}", msg)
      }
    }
  }
}
impl<T> ParseResult<T> for CResult<T> {
  fn res(self) -> Result<T> {
    self.into()
  }
  fn res_c(self) -> CResult<T> {
    self
  }
  fn un(self, _title: &str, add: &str) -> T {
    match self {
      Self::Ok(x) => x,
      Self::Err(e) => {
        let ref msg = format!("{e};{add}");
        #[cfg(feature = "dialog")]
        dialog_err_block(_title, msg);
        panic!("{}", msg)
      }
    }
  }
}
impl<T> ParseResult<T> for Option<T> {
  fn res(self) -> Result<T> {
    self.ok_or(Error::Option("ParseResult".into()))
  }
  fn res_c(self) -> CResult<T> {
    self.res().res_c()
  }
  fn un(self, _title: &str, add: &str) -> T {
    match self {
      Self::Some(x) => x,
      Self::None => {
        let ref msg = format!("{add}");
        #[cfg(feature = "dialog")]
        dialog_err_block(_title, msg);
        panic!("{}", msg)
      }
    }
  }
}
impl<T> ParseResult<T> for std::result::Result<T, Box<dyn std::any::Any + Send + Sync>> {
  fn res(self) -> Result<T> {
    match self {
      Self::Ok(r) => Result::Ok(r),
      Self::Err(e) => Result::Err(Error::any(e)),
    }
  }
  fn res_c(self) -> CResult<T> {
    self.res().res_c()
  }

  fn un(self, _title: &str, add: &str) -> T {
    match self {
      Self::Ok(x) => x,
      Self::Err(e) => {
        let ref msg = format!("{e:?};{add}");
        #[cfg(feature = "dialog")]
        dialog_err_block(_title, msg);
        panic!("{}", msg)
      }
    }
  }
}
impl<T> ParseResult<T> for std::result::Result<T, std::io::Error> {
  fn res(self) -> Result<T> {
    match self {
      Self::Ok(r) => Result::Ok(r),
      Self::Err(e) => Result::Err(Error::Io(e)),
    }
  }
  fn res_c(self) -> CResult<T> {
    self.res().res_c()
  }

  fn un(self, _title: &str, add: &str) -> T {
    match self {
      Self::Ok(x) => x,
      Self::Err(e) => {
        let ref msg = format!("{e};{add}");
        #[cfg(feature = "dialog")]
        dialog_err_block("Std Result io 错误", msg);
        panic!("{}", msg)
      }
    }
  }
}
impl<T> ParseResult<T> for std::result::Result<T, std::ffi::IntoStringError> {
  fn res(self) -> Result<T> {
    match self {
      Self::Ok(r) => Result::Ok(r),
      Self::Err(e) => Result::Err(Error::any(Box::new(e))),
    }
  }
  fn res_c(self) -> CResult<T> {
    self.res().res_c()
  }

  fn un(self, _title: &str, add: &str) -> T {
    match self {
      Self::Ok(x) => x,
      Self::Err(e) => {
        let ref msg = format!("{e};{add}");
        #[cfg(feature = "dialog")]
        dialog_err_block(_title, msg);
        panic!("{}", msg)
      }
    }
  }
}
impl<T> ParseResult<T> for std::result::Result<T, std::env::VarError> {
  fn res(self) -> Result<T> {
    match self {
      Self::Ok(r) => Result::Ok(r),
      Self::Err(e) => Result::Err(Error::any(Box::new(e))),
    }
  }
  fn res_c(self) -> CResult<T> {
    self.res().res_c()
  }

  fn un(self, _title: &str, add: &str) -> T {
    match self {
      Self::Ok(x) => x,
      Self::Err(e) => {
        let ref msg = format!("{e};{add}");
        #[cfg(feature = "dialog")]
        dialog_err_block(_title, msg);
        panic!("{}", msg)
      }
    }
  }
}

/// 解析格式
pub trait MyParseFormat {
  /// 解析所有
  fn parse_all(&self) -> Result<String>;
  /// 解析特殊关键词
  fn parse_format(&self) -> Result<String>;
  /// 解析自定义关键词
  fn parse_replace<F>(&self, start: char, end: char, match_value: F) -> Result<String>
  where
    F: Fn(String) -> String;
  /// 解析系统环境变量
  /// 解析跨平台系统环境变量(windows、linux、mac等)
  fn parse_env(&self) -> Result<String>;
  /// 解析路径规范,统一'/'
  fn parse_path(&self) -> String;
  /// 转Json Value
  fn to_value(&self) -> Result<Value>;
}
impl<S: AsRef<str>> MyParseFormat for S {
  fn parse_all(&self) -> Result<String> {
    self.as_ref().parse_format()?.parse_path().parse_env()
  }
  fn parse_format(&self) -> Result<String> {
    let local: DateTime<Local> = Local::now();
    Ok(
      REGEX_FORMAT_PATTERN
        .replace_all(self.as_ref(), |caps: &regex::Captures<'_>| {
          let key: String = caps.get(1).map_or("", |m| m.as_str()).to_lowercase();
          match &*key {
            // 获取日期
            "date" => format!(
              "{:04}-{:02}-{:02}",
              local.year(),
              local.month(),
              local.day()
            ),
            // 获取日期
            "time" => format!(
              "{:02}:{:02}:{:02}",
              local.hour(),
              local.minute(),
              local.second()
            ),
            // 获取时间戳
            "timestamp-millis" => local.timestamp_millis().to_string(),
            "day" => format!("{:02}", local.day()),
            "month" => format!("{:02}", local.month()),
            "year" => format!("{:02}", local.year()),
            "hour" => format!("{:02}", local.hour()),
            "minute" => format!("{:02}", local.minute()),
            "second" => format!("{:02}", local.second()),
            "cwd" => std::env::current_dir()
              .and_then(|x| Ok(x.display().to_string()))
              .def(),
            "origin" => get_original_dir()
              .and_then(|x| Ok(x.to_str().def().to_string()))
              .def(),
            "nanoid" => {
              #[cfg(feature = "algorithm")]
              return crate::algorithm!(nanoid 12);
              #[cfg(not(feature = "algorithm"))]
              return String::new();
            }
            _ => String::new(),
          }
        })
        .to_string(),
    )
  }
  fn parse_env(&self) -> Result<String> {
    Ok(
      REGEX_ENV_PATTERN
        .replace_all(self.as_ref(), |caps: &regex::Captures<'_>| {
          let key = caps.get(1).map_or("", |m| m.as_str());
          let var = std::env::var(key).def();
          var
        })
        .to_string(),
    )
  }

  fn to_value(&self) -> Result<Value> {
    Ok(serde_json::from_str::<Value>(self.as_ref())?)
  }
  fn parse_path(&self) -> String {
    self.as_ref().replace("\\\\", "/").replace("\\", "/")
  }
  fn parse_replace<F>(&self, start: char, end: char, match_callback: F) -> Result<String>
  where
    F: Fn(String) -> String,
  {
    let re = Regex::new(&format!(r"\{}([a-zA-Z0-9_]+)\{}", start, end))?;
    Ok(
      re.replace_all(self.as_ref(), |caps: &regex::Captures<'_>| {
        let key: String = caps.get(1).map_or("", |m| m.as_str()).to_lowercase();
        match_callback(key)
      })
      .to_string(),
    )
  }
}
impl MyParseFormat for Path {
  fn parse_format(&self) -> Result<String> {
    self.to_string_lossy().parse_format()
  }

  fn parse_env(&self) -> Result<String> {
    self.to_string_lossy().parse_env()
  }

  fn to_value(&self) -> Result<Value> {
    self.to_string_lossy().to_value()
  }

  fn parse_all(&self) -> Result<String> {
    self.to_string_lossy().parse_all()
  }
  fn parse_path(&self) -> String {
    self.to_string_lossy().parse_path()
  }

  fn parse_replace<F>(&self, start: char, end: char, match_value: F) -> Result<String>
  where
    F: Fn(String) -> String,
  {
    self
      .to_string_lossy()
      .parse_replace(start, end, match_value)
  }
}

/// 处理Json
pub trait AutoJson {
  /// 智能写入Json
  fn auto_write_json<T: Serialize>(&self, content: T) -> std::io::Result<()>;
  /// 智能读取Json
  fn auto_read_json<R: DeserializeOwned>(&self) -> std::io::Result<R>;
}

impl<S: Serialize + AsRef<Path>> AutoJson for S {
  fn auto_write_json<T: Serialize>(&self, content: T) -> std::io::Result<()> {
    let mut parent = self.as_ref().to_path_buf();
    parent.pop();
    if !parent.exists() {
      fs::create_dir_all(parent)?;
    }
    fs::write(self, serde_json::to_string_pretty(&content)?)?;
    std::io::Result::Ok(())
  }

  fn auto_read_json<R: DeserializeOwned>(&self) -> std::io::Result<R> {
    std::io::Result::Ok(serde_json::from_str::<R>(&std::fs::read_to_string(
      self.as_ref(),
    )?)?)
  }
}

/// 自动检查创建目录
pub trait AutoPath {
  /// 自检查创建目录
  fn auto_create_dir(&self) -> Result<()>;
  /// 自检查移除目录
  fn auto_remove_dir(&self) -> Result<()>;
  /// 自检查创建文件
  fn auto_create_file<S>(&self, content: S) -> Result<()>
  where
    S: AsRef<str>;
  /// 自检查移除文件
  fn auto_remove_file(&self) -> Result<()>;
}

impl<T: AsRef<str>> AutoPath for T {
  fn auto_create_dir(&self) -> Result<()> {
    Path::new(self.as_ref()).auto_create_dir()
  }

  fn auto_remove_dir(&self) -> Result<()> {
    Path::new(self.as_ref()).auto_remove_dir()
  }

  fn auto_create_file<S>(&self, content: S) -> Result<()>
  where
    S: AsRef<str>,
  {
    Path::new(self.as_ref()).auto_create_file(content)
  }

  fn auto_remove_file(&self) -> Result<()> {
    Path::new(self.as_ref()).auto_remove_file()
  }
}
impl AutoPath for Path {
  fn auto_create_dir(&self) -> Result<()> {
    let x = if self.is_dir() {
      self
    } else {
      self.parent().ok_or(Error::String(format!(
        "{} -> {}",
        self.to_string_lossy(),
        io::ErrorKind::InvalidData.to_string()
      )))?
    };
    if !x.exists() {
      fs::create_dir_all(x)?;
    }
    Ok(())
  }

  fn auto_remove_dir(&self) -> Result<()> {
    if self.is_dir() {
      if self.exists() {
        fs::remove_dir_all(self)?;
        if self.exists() {
          return Err(Error::Str(
            format!(
              "{} -> {}",
              self.to_string_lossy(),
              io::ErrorKind::AlreadyExists.to_string()
            )
            .into(),
          ));
        }
      }
    } else {
      return Err(Error::Str(
        format!(
          "{} -> {}",
          self.to_string_lossy(),
          io::ErrorKind::Unsupported.to_string()
        )
        .into(),
      ));
    }
    Ok(())
  }

  fn auto_create_file<S>(&self, data: S) -> Result<()>
  where
    S: AsRef<str>,
  {
    if !self.exists() {
      fs::write(self, data.as_ref())?;
    } else if !self.is_file() {
      return Err(Error::Str(
        format!(
          "{} -> {}",
          self.to_string_lossy(),
          io::ErrorKind::AlreadyExists.to_string()
        )
        .into(),
      ));
    }
    Ok(())
  }

  fn auto_remove_file(&self) -> Result<()> {
    if self.exists() && self.is_file() {
      fs::remove_file(self)?;
    } else if !self.is_file() {
      return Err(Error::Str(
        format!(
          "{} -> {}",
          self.to_string_lossy(),
          io::ErrorKind::AlreadyExists.to_string()
        )
        .into(),
      ));
    }
    Ok(())
  }
}

/// Serializer for raw pointer
pub mod raw_pointer_serializer {
  use serde::{Deserialize, Deserializer, Serializer};

  use super::{any_to_c_mut_ptr, c_mut_ptr_to_any};
  /// Serializer for function pointer
  pub fn serialize<S>(raw_ptr: &*mut std::ffi::c_void, serializer: S) -> Result<S::Ok, S::Error>
  where
    S: Serializer,
  {
    let raw_ptr_address =
      unsafe { c_mut_ptr_to_any::<u64>(*raw_ptr) }.expect("raw_pointer_serializer serialize");
    serializer.serialize_u64(*raw_ptr_address)
  }
  /// Serializer for function pointer
  pub fn deserialize<'de, D>(deserializer: D) -> Result<*mut std::ffi::c_void, D::Error>
  where
    D: Deserializer<'de>,
  {
    let raw_ptr_address: u64 = Deserialize::deserialize(deserializer)?;
    let raw_ptr = any_to_c_mut_ptr(Box::new(raw_ptr_address));
    Ok(raw_ptr)
  }
}
/// Serializer for raw pointer
pub mod c_str_pointer_serializer {
  use super::{AutoParse as _, CAutoParse as _};
  use serde::{Deserialize, Deserializer, Serializer};
  /// Serializer for function pointer
  pub fn serialize<S>(
    raw_ptr: &*const std::ffi::c_char,
    serializer: S,
  ) -> std::result::Result<S::Ok, S::Error>
  where
    S: Serializer,
  {
    serializer.serialize_str(&*unsafe { raw_ptr.c_to_string() })
  }
  /// Serializer for function pointer
  pub fn deserialize<'de, D>(
    deserializer: D,
  ) -> std::result::Result<*const std::ffi::c_char, D::Error>
  where
    D: Deserializer<'de>,
  {
    let raw_ptr_address: &str = Deserialize::deserialize(deserializer)?;
    Ok(raw_ptr_address.to_c_char())
  }
}

#[cfg(feature = "ui")]
#[cfg(target_os = "windows")]
/// Serializer for raw pointer
pub mod hwnd_serializer {
  use crate::ui::HWND;
  use serde::{Deserialize, Deserializer, Serializer};
  /// Serializer for function pointer
  pub fn serialize<S>(raw_ptr: &HWND, serializer: S) -> Result<S::Ok, S::Error>
  where
    S: Serializer,
  {
    let raw_ptr_address = *raw_ptr as *mut std::ffi::c_void as usize;
    serializer.serialize_u64(raw_ptr_address as u64)
  }
  /// Serializer for function pointer
  pub fn deserialize<'de, D>(deserializer: D) -> Result<HWND, D::Error>
  where
    D: Deserializer<'de>,
  {
    let raw_ptr_address: u64 = Deserialize::deserialize(deserializer)?;
    let raw_ptr = raw_ptr_address as *mut std::ffi::c_void as HWND;
    Ok(raw_ptr)
  }
}
