use fmt::Debug;
use std::{
convert::TryFrom,
fmt::{self, Formatter},
};
use inflector::cases::snakecase::to_snake_case;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Ident, Path, Type};
use crate::util::to_ident;
pub(crate) struct RustType(Path);
impl Debug for RustType {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let path = &self.0;
write!(f, "{}", quote!(#path))
}
}
impl RustType {
pub fn new(path: Path) -> Self {
RustType(path)
}
pub fn ident(&self) -> Ident {
self.0
.segments
.last()
.expect("type has no last part?")
.ident
.clone()
}
pub fn ty(&self) -> TokenStream {
let ident = self.ident();
let args = &self
.0
.segments
.last()
.expect("type has no last part?")
.arguments;
quote!(#ident #args)
}
pub fn as_given(&self) -> &Path {
&self.0
}
pub fn module_ident(&self) -> Ident {
to_ident(&to_snake_case(&self.ident().to_string()))
}
}
impl TryFrom<Type> for RustType {
type Error = String;
fn try_from(value: Type) -> core::result::Result<Self, Self::Error> {
match value {
Type::Path(type_path) => Ok(RustType(type_path.path)),
broken => Err(format!("cannot convert input {:?} to RustType", broken)),
}
}
}