use crate::constants::{LEFT, RIGHT};
use crate::utils::{
get_any_attribute_by_meta_prefix, meta_not_found_in_all_fields, resolve_first_field,
};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{Data, Field, Generics};
pub fn impl_left_right(ident: &Ident, data: &Data, generics: &Generics) -> TokenStream {
let left_field = resolve_first_field(
data,
&is_left_field,
true,
&meta_not_found_in_all_fields(LEFT, &ident.to_string()),
)
.unwrap();
let right_field = resolve_first_field(
data,
&is_right_field,
true,
&meta_not_found_in_all_fields(RIGHT, &ident.to_string()),
)
.unwrap();
let left_field_ident = left_field.ident;
let left_field_ty = left_field.ty;
let right_field_ident = right_field.ident;
let right_field_ty = right_field.ty;
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
quote! {
impl #impl_generics LeftRight for #ident #type_generics #where_clause {
type L = #left_field_ty;
type R = #right_field_ty;
fn left(&self) -> &Self::L {
&self.#left_field_ident
}
fn right(&self) -> &Self::R {
&self.#right_field_ident
}
fn into_tuple(self) -> (Self::L, Self::R) {
(self.#left_field_ident, self.#right_field_ident)
}
}
}
}
fn is_left_field(field: &Field) -> bool {
get_any_attribute_by_meta_prefix(LEFT, &field.attrs, false, "").is_some()
}
fn is_right_field(field: &Field) -> bool {
get_any_attribute_by_meta_prefix(RIGHT, &field.attrs, false, "").is_some()
}