Skip to content

Instantly share code, notes, and snippets.

@hgzimmerman
Created December 28, 2019 02:20
Show Gist options
  • Save hgzimmerman/cc34388ee7831043ddb882925aa6b288 to your computer and use it in GitHub Desktop.
Save hgzimmerman/cc34388ee7831043ddb882925aa6b288 to your computer and use it in GitHub Desktop.
pub(crate) fn extract_type_from_callback(ty: &syn::Type) -> Option<&syn::Type> {
use syn::{GenericArgument, Path, PathArguments, PathSegment};
fn extract_type_path(ty: &syn::Type) -> Option<&Path> {
match *ty {
syn::Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path),
_ => None,
}
}
fn extract_option_segment(path: &Path) -> Option<&PathSegment> {
let idents_of_path = path
.segments
.iter()
.into_iter()
.fold(String::new(), |mut acc, v| {
acc.push_str(&v.ident.to_string());
acc.push('|');
acc
});
vec!["Callback|", "yew|Callback|"]
.into_iter()
.find(|s| &idents_of_path == *s)
.and_then(|_| path.segments.last())
}
extract_type_path(ty)
.and_then(|path| extract_option_segment(path))
.and_then(|pair_path_segment| {
let type_params = &pair_path_segment.arguments;
// It should have only on angle-bracketed param ("<String>"):
match *type_params {
PathArguments::AngleBracketed(ref params) => params.args.first(),
_ => None,
}
})
.and_then(|generic_arg| match *generic_arg {
GenericArgument::Type(ref ty) => Some(ty),
_ => None,
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment