use std::borrow::Cow;
use std::collections::HashMap;
use syn::{Attribute, GenericArgument, PathArguments, Type};
pub fn get_diesel_type_name(ty: &Type) -> &'static str {
match get_type_name(&ty).as_str() {
"bool" => "Bool",
"i32" => "Integer",
"String" => "Text",
"DateTime" | "UtcDateTime" => "Timestamptz",
"LocaleDate" | "UtcDate" => "Date",
"f64" => "Double",
"f32" => "Float",
"i64" => "BigInt",
others => panic!("unsupported field type: {}, please add type support in derives", &others),
}
}
pub fn get_struct_attributes(attrs: &Vec<Attribute>) -> HashMap<String, Option<String>> {
attrs
.iter()
.map(|attr| {
let name = attr.path.segments.iter().map(|f| f.ident.to_string()).collect::<Vec<_>>().join(".");
let value = attr.clone().tokens.into_iter().collect::<Vec<_>>().get(1).map(|f| format!("{}", f).replace("\"", ""));
(name, value)
})
.collect::<HashMap<_, _>>()
}
pub fn get_struct_attribute(attrs: &Vec<Attribute>, name: &str) -> Option<String> {
match get_struct_attributes(attrs).get(name) {
Some(Some(x)) => Some(x.clone()),
_ => None,
}
}
#[allow(dead_code)]
pub fn snake_to_camel(s: &str) -> Cow<str> {
if s.contains("_") {
let mut buffer = String::with_capacity(s.len());
let mut under = false;
for c in s.chars() {
match c {
'_' => under = true,
_ => {
if under {
buffer.push_str(&c.to_uppercase().to_string());
under = false;
} else {
buffer.push(c)
}
}
}
}
Cow::Owned(buffer)
} else {
Cow::Borrowed(s)
}
}
#[allow(dead_code)]
pub fn default_true() -> bool {
true
}
pub fn is_optional(ty: &Type) -> bool {
if let Type::Path(tp) = ty {
if let Some(segment) = tp.path.segments.last() {
let name = format!("{}", &segment.ident);
return &name == "Option" || &name == "std::option::Option";
}
}
return false;
}
pub fn unwrap_type(ty: &Type) -> Cow<Type> {
if let Type::Path(tp) = ty {
if let Some(segment) = tp.path.segments.last() {
let ident = &segment.ident;
let name = format!("{}", ident);
if &name == "Option" {
if let PathArguments::AngleBracketed(generic_arguments) = &segment.arguments {
if let Some(GenericArgument::Type(subty)) = generic_arguments.args.first() {
return Cow::Borrowed(subty);
}
}
}
}
}
Cow::Borrowed(ty)
}
pub fn get_type_name(ty: &Type) -> String {
if let syn::Type::Path(tp) = unwrap_type(&ty).into_owned() {
tp.path.segments.iter().map(|seg| format!("{}", seg.ident)).collect::<Vec<_>>().join(".")
} else {
"".to_owned()
}
}