use crate::meta_types::KeywordToken;
pub(crate) trait TrySet<T> {
fn try_set(self, to: &mut T) -> syn::Result<()>;
}
pub(crate) enum TrySetError {
Infallible,
Syn(syn::Error),
}
impl From<core::convert::Infallible> for TrySetError {
fn from(_: core::convert::Infallible) -> Self {
Self::Infallible
}
}
impl From<syn::Error> for TrySetError {
fn from(error: syn::Error) -> Self {
Self::Syn(error)
}
}
impl<T: TryInto<To, Error = E> + KeywordToken, E: Into<TrySetError>, To> TrySet<Option<To>> for T {
fn try_set(self, to: &mut Option<To>) -> syn::Result<()> {
if to.is_none() {
*to = Some(self.try_into().map_err(|error| match error.into() {
TrySetError::Infallible => unreachable!(),
TrySetError::Syn(error) => error,
})?);
Ok(())
} else {
Err(syn::Error::new(
self.keyword_span(),
format!("conflicting {} keyword", self.dyn_display()),
))
}
}
}
impl<T: TryInto<To, Error = syn::Error> + KeywordToken, To> TrySet<Vec<To>> for T {
fn try_set(self, to: &mut Vec<To>) -> syn::Result<()> {
to.push(self.try_into()?);
Ok(())
}
}