use proc_macro2::TokenStream;
use quote::quote;
use std::str::FromStr;
pub enum HsType {
CString,
Empty,
IO(Box<HsType>),
}
impl ToString for HsType {
fn to_string(&self) -> String {
match self {
HsType::CString => "CString".to_string(),
HsType::Empty => "()".to_string(),
HsType::IO(x) => format!("IO ({})", x.to_string()),
}
}
}
impl FromStr for HsType {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"CString" => Ok(HsType::CString),
"()" => Ok(HsType::Empty),
_ => Err(()),
}
}
}
impl HsType {
pub fn quote(&self) -> TokenStream {
match self {
HsType::CString => quote! { *const std::os::raw::c_char },
HsType::Empty => quote! { () },
HsType::IO(x) => x.quote(),
}
}
}
pub trait ReprHs {
fn into() -> HsType;
}
impl ReprHs for String {
fn into() -> HsType {
HsType::CString
}
}
impl ReprHs for &str {
fn into() -> HsType {
HsType::CString
}
}
impl ReprHs for () {
fn into() -> HsType {
HsType::Empty
}
}
pub trait ReprC<T> {
fn from(_: T) -> Self;
}
impl ReprC<*const std::os::raw::c_char> for &str {
#[allow(clippy::not_unsafe_ptr_arg_deref)]
fn from(x: *const std::os::raw::c_char) -> Self {
unsafe { std::ffi::CStr::from_ptr(x) }.to_str().unwrap()
}
}
impl ReprC<*const std::os::raw::c_char> for String {
fn from(x: *const std::os::raw::c_char) -> Self {
let r: &str = ReprC::from(x);
r.to_string()
}
}