use crate::ident::{
StaticIdent, FALLIBLE_FN_IDENT, FALLIBLE_TRAIT_IDENT, FN_IDENT,
NO_DROP_MARKER_FALLIBLE_TRAIT_IDENT, NO_DROP_MARKER_TRAIT_IDENT, TRAIT_IDENT,
};
use proc_macro2::TokenStream;
use quote::quote;
#[derive(Copy, Clone, Debug)]
pub(crate) enum Derivable {
Standard,
Fallible,
}
impl Derivable {
pub(crate) fn trait_ident(self) -> StaticIdent {
match self {
Self::Standard => TRAIT_IDENT,
Self::Fallible => FALLIBLE_TRAIT_IDENT,
}
}
pub(crate) fn no_drop_marker_trait_ident(self) -> StaticIdent {
match self {
Self::Standard => NO_DROP_MARKER_TRAIT_IDENT,
Self::Fallible => NO_DROP_MARKER_FALLIBLE_TRAIT_IDENT,
}
}
pub(crate) fn fn_ident(self) -> StaticIdent {
match self {
Self::Standard => FN_IDENT,
Self::Fallible => FALLIBLE_FN_IDENT,
}
}
pub(crate) fn bind_expr(self, expr: TokenStream) -> TokenStream {
match self {
Self::Standard => expr,
Self::Fallible => quote!(#expr?),
}
}
pub(crate) fn unit_expr(self, expr: TokenStream) -> TokenStream {
match self {
Self::Standard => expr,
Self::Fallible => quote!(::core::result::Result::Ok(#expr)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use syn::{parse_quote, Expr};
#[test]
fn bind_for_standard_returns_expression_unchanged() {
let bound = Derivable::Standard.bind_expr(quote!(value));
let expr: Result<Expr, _> = syn::parse2(bound);
assert!(expr.is_ok());
assert_eq!(expr.unwrap(), parse_quote!(value));
}
#[test]
fn bind_for_fallible_wraps_expression_with_question_mark() {
let bound = Derivable::Fallible.bind_expr(quote!(value));
let expr: Result<Expr, _> = syn::parse2(bound);
assert!(expr.is_ok());
assert_eq!(expr.unwrap(), parse_quote!(value?));
}
#[test]
fn unit_for_standard_returns_expression_unchanged() {
let bound = Derivable::Standard.unit_expr(quote!(value));
let expr: Result<Expr, _> = syn::parse2(bound);
assert!(expr.is_ok());
assert_eq!(expr.unwrap(), parse_quote!(value));
}
#[test]
fn unit_for_fallible_wraps_expression_in_ok() {
let bound = Derivable::Fallible.unit_expr(quote!(value));
let expr: Result<Expr, _> = syn::parse2(bound);
assert!(expr.is_ok());
assert_eq!(
expr.unwrap(),
parse_quote!(::core::result::Result::Ok(value))
);
}
}