use std::fmt::{Debug, Formatter, Result as FmtResult, Write};
use jl_sys::{jl_char_type, jl_unbox_uint32};
use super::is_bits::IsBits;
use crate::{
convert::{ccall_types::CCallReturn, unbox::Unbox},
data::managed::{private::ManagedPriv, value::Value},
impl_julia_typecheck, impl_valid_layout,
private::Private,
};
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Char(u32);
impl Char {
#[inline]
pub const fn new(val: char) -> Self {
Char(val as u32)
}
#[inline]
pub const fn as_u32(self) -> u32 {
self.0
}
#[inline]
pub const fn try_as_char(self) -> Option<char> {
char::from_u32(self.0)
}
#[inline]
pub unsafe fn try_as_char_unchecked(self) -> char {
unsafe { char::from_u32_unchecked(self.0) }
}
}
impl<'scope> Debug for Char {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
if let Some(ch) = char::from_u32(self.0) {
f.write_char(ch)
} else {
f.write_fmt(format_args!("{:#010x} <invalid char>", self.0))
}
}
}
impl_julia_typecheck!(Char, jl_char_type);
impl_valid_layout!(Char, jl_char_type);
unsafe impl Unbox for Char {
type Output = Self;
#[inline]
unsafe fn unbox(value: Value) -> Char {
unsafe { Char(jl_unbox_uint32(value.unwrap(Private).cast())) }
}
}
unsafe impl Unbox for char {
type Output = Char;
#[inline]
unsafe fn unbox(value: Value) -> Char {
unsafe { Char(jl_unbox_uint32(value.unwrap(Private).cast())) }
}
}
impl_ccall_arg!(Char);
unsafe impl CCallReturn for Char {
type FunctionReturnType = Self;
type CCallReturnType = Self;
type ReturnAs = Self;
#[inline]
unsafe fn return_or_throw(self) -> Self::ReturnAs {
self
}
}
unsafe impl CCallReturn for char {
type FunctionReturnType = Char;
type CCallReturnType = Char;
type ReturnAs = Char;
#[inline]
unsafe fn return_or_throw(self) -> Self::ReturnAs {
Char(self as u32)
}
}
impl_construct_julia_type!(Char, jl_char_type);
unsafe impl IsBits for Char {}