use proc_macro2::TokenStream;
use syn::{GenericArgument, PathArguments, Type};
use crate::error::*;
#[allow(clippy::large_enum_variant)]
#[allow(dead_code)]
pub enum FieldType {
Normal(Type),
Optional { inner: Type, outer: Type },
Invalid,
}
pub fn determine_field_type(ty: Type) -> Result<FieldType, TokenStream> {
match ty.clone() {
Type::Path(type_path) => {
if type_path.qself.is_some() {
return Ok(FieldType::Normal(ty));
}
let path = type_path.path;
if path.leading_colon.is_some() || path.segments.len() > 1 {
return Ok(FieldType::Normal(ty));
}
let segment = if let Some(segment) = path.segments.iter().next() {
segment
} else {
return Ok(FieldType::Normal(ty));
};
if segment.ident != "Option" {
return Ok(FieldType::Normal(ty));
}
let generic_arg = match &segment.arguments {
PathArguments::AngleBracketed(params) => {
if let Some(arg) = params.args.iter().next() {
arg
} else {
return Err(err!(ty, "Option doesn't have a type parameter.."));
}
}
_ => {
return Err(err!(
ty,
"Unknown path arguments behind Option. Please report this."
))
}
};
match generic_arg {
GenericArgument::Type(inner_type) => Ok(FieldType::Optional {
inner: inner_type.clone(),
outer: ty,
}),
_ => Err(err!(ty, "Option path argument isn't a type.")),
}
}
_ => Err(err!(
ty,
"Found a non-path type. This isn't supported in inter-struct yet."
)),
}
}