use crate::set_literals;
use crate::FXAttributes;
use crate::FXBool;
use crate::FXDoc;
use crate::FXOrig;
use crate::FXProp;
use crate::FXPropBool;
use crate::FXPunctuated;
use crate::FXSetState;
use crate::FXString;
use crate::FXSynValue;
use crate::FXTryInto;
use crate::FromNestAttr;
use darling::util::Flag;
use darling::FromMeta;
use fieldx_derive_support::fxhelper;
use getset::Getters;
use proc_macro2::TokenStream;
use syn::Token;
#[fxhelper(validate = Self::validate, to_tokens)]
#[derive(Debug, Default)]
pub struct FXBuilderHelper<const STRUCT: bool = false> {
#[getset(skip)]
attributes: Option<FXAttributes>,
#[getset(skip)]
attributes_impl: Option<FXAttributes>,
#[getset(get = "pub")]
into: Option<FXBool>,
#[getset(get = "pub")]
required: Option<FXBool>,
opt_in: Option<FXBool>,
post_build: Option<FXSynValue<syn::Ident, true>>,
#[getset(get = "pub")]
error: Option<FXSynValue<FXPunctuated<syn::Path, Token![,], 1, 2>>>,
prefix: Option<FXString>,
method_doc: Option<FXDoc>,
}
impl<const STRUCT: bool> FXBuilderHelper<STRUCT> {
#[inline]
pub fn is_into(&self) -> Option<FXProp<bool>> {
self.into.as_ref().map(|i| i.into())
}
#[inline]
pub fn is_required(&self) -> Option<FXProp<bool>> {
self.required.as_ref().map(|r| r.into())
}
pub fn has_post_build(&self) -> FXProp<bool> {
self.post_build
.as_ref()
.map_or_else(|| FXProp::new(false, None), |pb| FXProp::new(true, pb.orig_span()))
}
#[inline]
pub fn attributes(&self) -> Option<&FXAttributes> {
self.attributes.as_ref()
}
#[inline]
pub fn attributes_impl(&self) -> Option<&FXAttributes> {
self.attributes_impl.as_ref()
}
pub fn error_type(&self) -> Option<&syn::Path> {
self.error().as_ref().and_then(|ev| ev.first())
}
#[inline]
pub fn error_variant(&self) -> Option<&syn::Path> {
self.error().as_ref().and_then(|ev| ev.get(1))
}
#[inline]
pub fn method_doc(&self) -> Option<&FXDoc> {
self.method_doc.as_ref()
}
#[inline]
pub fn post_build(&self) -> Option<&FXSynValue<syn::Ident, true>> {
self.post_build.as_ref()
}
#[inline]
pub fn prefix(&self) -> Option<&FXString> {
self.prefix.as_ref()
}
#[inline]
pub fn opt_in(&self) -> Option<&FXBool> {
self.opt_in.as_ref()
}
#[doc(hidden)]
pub fn validate(&self) -> darling::Result<()> {
if !STRUCT {
if self.error.is_some() {
return Err(
darling::Error::custom(format!("parameter 'error' is only supported at struct level"))
.with_span(&self.error.final_span()),
);
}
if self.post_build.is_some() {
return Err(darling::Error::custom(format!(
"parameter 'post_build' is only supported at struct level"
))
.with_span(&self.post_build.final_span()));
}
if self.opt_in.is_some() {
return Err(
darling::Error::custom(format!("parameter 'opt_in' is only supported at struct level"))
.with_span(&self.opt_in.final_span()),
);
}
}
Ok(())
}
}
impl<const STRUCT: bool> FromNestAttr for FXBuilderHelper<STRUCT> {
set_literals! {builder, ..1 => name}
fn for_keyword(_path: &syn::Path) -> darling::Result<Self> {
Ok(Self::default())
}
}