#![allow(dead_code)]
use syn::{Path, Type};
pub fn to_snake_case(s: &str) -> String {
s.split("::")
.last()
.unwrap_or(s)
.chars()
.enumerate()
.flat_map(|(i, c)| {
if c.is_uppercase() && i > 0 {
vec!['_', c.to_lowercase().next().unwrap()]
} else {
vec![c.to_lowercase().next().unwrap()]
}
})
.collect()
}
pub fn to_pascal_case(s: &str) -> String {
s.split('_')
.map(|word| {
let mut c = word.chars();
match c.next() {
None => String::new(),
Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
}
})
.collect()
}
pub fn path_to_string(path: &Path) -> String {
path.segments
.iter()
.map(|seg| seg.ident.to_string())
.collect::<Vec<_>>()
.join("::")
}
pub fn is_primitive_or_wrapper(ty: &Type) -> bool {
match ty {
Type::Path(type_path) => {
if let Some(segment) = type_path.path.segments.last() {
let type_name = segment.ident.to_string();
matches!(
type_name.as_str(),
"u8" | "u16"
| "u32"
| "u64"
| "u128"
| "i8"
| "i16"
| "i32"
| "i64"
| "i128"
| "f32"
| "f64"
| "bool"
| "String"
| "Option"
| "Vec"
)
} else {
false
}
}
_ => true,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_to_snake_case() {
assert_eq!(to_snake_case("MyTypeName"), "my_type_name");
assert_eq!(to_snake_case("HTTPServer"), "h_t_t_p_server");
assert_eq!(to_snake_case("module::MyType"), "my_type");
}
#[test]
fn test_to_pascal_case() {
assert_eq!(to_pascal_case("my_type_name"), "MyTypeName");
assert_eq!(to_pascal_case("hello"), "Hello");
}
}