use std::collections::{HashMap, HashSet};
pub use rts_derive::rts_to_string;
pub use rts_derive::RTS;
pub trait RTS<A1 = (), A2 = (), B = ()> {
fn to_type_string(&self) -> String {
"any".into()
}
fn to_type_name(&self) -> String {
"any".into()
}
}
macro_rules! impl_rts_number {
( $( $a:ty ) * ) => {
$(
impl RTS for $a {
fn to_type_string(&self)->String{
"number".into()
}
fn to_type_name(&self)->String{
"number".into()
}
}
)*
};
}
macro_rules! impl_rts {
( $( ($a:ty, $b:expr) ) , * ) => {
$(
impl RTS for $a {
fn to_type_string(&self)->String{
$b.into()
}
fn to_type_name(&self)->String{
$b.into()
}
}
)*
};
}
impl<K: RTS + Default, V: RTS + Default> RTS for HashMap<K, V> {
fn to_type_string(&self) -> String {
format!(
"Map<{}, {}>",
K::default().to_type_string(),
V::default().to_type_string(),
)
}
fn to_type_name(&self) -> String {
format!(
"Map<{}, {}>",
K::default().to_type_name(),
V::default().to_type_name(),
)
}
}
impl<V: RTS + Default> RTS for HashSet<V> {
fn to_type_string(&self) -> String {
format!("Set<{}>", V::default().to_type_string(),)
}
fn to_type_name(&self) -> String {
format!("Set<{}>", V::default().to_type_name(),)
}
}
impl<V: RTS + Default> RTS for Vec<V> {
fn to_type_string(&self) -> String {
format!("Array<{}>", V::default().to_type_string(),)
}
fn to_type_name(&self) -> String {
format!("Array<{}>", V::default().to_type_name(),)
}
}
fn get_name(s: &str) -> &str {
s.split("::").last().expect("function name error")
}
impl_rts_number!(i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 );
impl_rts!((bool, "bool"), (char, "string"), (String, "string"));
impl<F, A, R> RTS<(A), (R)> for F
where
F: Fn(A) -> R,
A: RTS,
R: RTS,
{
fn to_type_string(&self) -> String {
let fn_name = heck::AsLowerCamelCase(get_name(std::any::type_name::<F>()));
let arg_name = get_name(std::any::type_name::<A>());
let rt_name = get_name(std::any::type_name::<R>());
format!(
"declare function {}(arg0: {}): {};",
fn_name, arg_name, rt_name
)
}
fn to_type_name(&self) -> String {
"any".into()
}
}
impl<F> RTS for F
where
F: Fn(),
{
fn to_type_string(&self) -> String {
let fn_name = heck::AsLowerCamelCase(get_name(std::any::type_name::<F>()));
format!("declare function {}();", fn_name)
}
fn to_type_name(&self) -> String {
"any".into()
}
}
impl<F, R> RTS<R> for F
where
F: Fn() -> R,
R: RTS,
{
fn to_type_string(&self) -> String {
let fn_name = heck::AsLowerCamelCase(get_name(std::any::type_name::<F>()));
let rt_name = get_name(std::any::type_name::<R>());
format!("declare function {}(): {};", fn_name, rt_name)
}
fn to_type_name(&self) -> String {
"any".into()
}
}
impl<F, A1, A2, R> RTS<A1, A2, R> for F
where
F: Fn(A1, A2) -> R,
A1: RTS,
A2: RTS,
R: RTS,
{
fn to_type_string(&self) -> String {
let fn_name = heck::AsLowerCamelCase(get_name(std::any::type_name::<F>()));
let rt_name = get_name(std::any::type_name::<R>());
let arg1_name = get_name(std::any::type_name::<A1>());
let arg2_name = get_name(std::any::type_name::<A2>());
format!(
"declare function {}(arg0: {}, arg1: {}): {};",
fn_name, arg1_name, arg2_name, rt_name
)
}
fn to_type_name(&self) -> String {
"any".into()
}
}