use proc_macro2::TokenStream;
use quote::quote;
use syn::Type;
pub struct PropTypeInfo {
pub prop_type_expr: TokenStream,
pub rust_type: TokenStream,
pub getter_fn: syn::Ident,
pub setter_fn: syn::Ident,
pub zero_expr: TokenStream,
}
pub fn map_type(ty: &Type) -> Option<PropTypeInfo> {
let type_str = match ty {
Type::Path(tp) => {
let seg = tp.path.segments.last()?;
seg.ident.to_string()
}
_ => return None,
};
let ident = |s: &str| syn::Ident::new(s, proc_macro2::Span::call_site());
let info = match type_str.as_str() {
"bool" => PropTypeInfo {
prop_type_expr: quote! { ::rusteal_runtime::ffi::RustealReifyPropType::Bool },
rust_type: quote! { bool },
getter_fn: ident("get_bool"),
setter_fn: ident("set_bool"),
zero_expr: quote! { false },
},
"i32" => PropTypeInfo {
prop_type_expr: quote! { ::rusteal_runtime::ffi::RustealReifyPropType::Int32 },
rust_type: quote! { i32 },
getter_fn: ident("get_i32"),
setter_fn: ident("set_i32"),
zero_expr: quote! { 0i32 },
},
"i64" => PropTypeInfo {
prop_type_expr: quote! { ::rusteal_runtime::ffi::RustealReifyPropType::Int64 },
rust_type: quote! { i64 },
getter_fn: ident("get_i64"),
setter_fn: ident("set_i64"),
zero_expr: quote! { 0i64 },
},
"u8" => PropTypeInfo {
prop_type_expr: quote! { ::rusteal_runtime::ffi::RustealReifyPropType::UInt8 },
rust_type: quote! { u8 },
getter_fn: ident("get_u8"),
setter_fn: ident("set_u8"),
zero_expr: quote! { 0u8 },
},
"f32" => PropTypeInfo {
prop_type_expr: quote! { ::rusteal_runtime::ffi::RustealReifyPropType::Float },
rust_type: quote! { f32 },
getter_fn: ident("get_f32"),
setter_fn: ident("set_f32"),
zero_expr: quote! { 0.0f32 },
},
"f64" => PropTypeInfo {
prop_type_expr: quote! { ::rusteal_runtime::ffi::RustealReifyPropType::Double },
rust_type: quote! { f64 },
getter_fn: ident("get_f64"),
setter_fn: ident("set_f64"),
zero_expr: quote! { 0.0f64 },
},
_ => return None,
};
Some(info)
}
pub fn to_pascal_case(s: &str) -> String {
s.split('_')
.filter(|part| !part.is_empty())
.map(|part| {
let mut chars = part.chars();
match chars.next() {
Some(c) => {
let upper: String = c.to_uppercase().collect();
upper + chars.as_str()
}
None => String::new(),
}
})
.collect()
}
pub fn fnv1a_hash(s: &str) -> u64 {
const FNV_OFFSET: u64 = 0xcbf29ce484222325;
const FNV_PRIME: u64 = 0x100000001b3;
let mut hash = FNV_OFFSET;
for &b in s.as_bytes() {
hash ^= b as u64;
hash = hash.wrapping_mul(FNV_PRIME);
}
hash
}