use std::marker::PhantomData;
use crate::{
__private_types::types::Resolver,
schema::{
fields::{
base::{BuildableFieldConfig, FieldConfig, FieldType, InternalFieldConfig},
types::{
DefaultValue, IntoDefaultValueResolver, IntoDeleteHandler, IntoSuccessHandler,
IntoUniformResolver, IsFieldProvisionEnabled,
},
},
types::{
DeleteHandler, FieldValue, IsProvided, IsProvidedButNotComputed, No, SuccessHandler,
Yes, YesComputed,
},
},
types::internal::{
types::{erase_value, ErasedValue},
DefaultErrorSanitizer, IvoErrorSanitizer,
},
IvoStruct,
};
pub struct DependentFieldBuilder<
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions> = DefaultErrorSanitizer,
HasDefault = No,
HasParents = No,
HasResolver = No,
HasReadonly = No,
HasDelete = No,
HasSuccess = No,
> {
name: &'static str,
default: Option<DefaultValue<ErasedValue, I, CtxOptions>>,
depends_on: Option<Vec<&'static str>>,
resolver: Option<Resolver<ErasedValue, I, O, CtxOptions>>,
ignore_update: Option<IsFieldProvisionEnabled<I, O, CtxOptions>>,
on_delete_fns: Option<Vec<DeleteHandler<O, CtxOptions>>>,
on_success_fns: Option<Vec<SuccessHandler<I, O, CtxOptions>>>,
_t: PhantomData<T>,
_err: PhantomData<ErrorSanitizer>,
_default: PhantomData<HasDefault>,
_depends_on: PhantomData<HasParents>,
_resolver: PhantomData<HasResolver>,
_del_handlers: PhantomData<HasDelete>,
_readonly: PhantomData<HasReadonly>,
_success_handlers: PhantomData<HasSuccess>,
}
impl<
HasDefault,
HasParents,
HasResolver,
HasReadonly,
HasDelete,
HasSuccess,
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions>,
>
DependentFieldBuilder<
T,
I,
O,
CtxOptions,
ErrorSanitizer,
HasDefault,
HasParents,
HasResolver,
HasReadonly,
HasDelete,
HasSuccess,
>
{
pub const fn new(name: &'static str) -> Self {
Self {
name,
default: None,
depends_on: None,
resolver: None,
ignore_update: None,
on_delete_fns: None,
on_success_fns: None,
_t: PhantomData,
_err: PhantomData,
_default: PhantomData,
_depends_on: PhantomData,
_readonly: PhantomData,
_resolver: PhantomData,
_del_handlers: PhantomData,
_success_handlers: PhantomData,
}
}
}
impl<
HasDefault,
HasParents,
HasResolver,
HasReadonly,
HasDelete,
HasSuccess,
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions>,
> Default
for DependentFieldBuilder<
T,
I,
O,
CtxOptions,
ErrorSanitizer,
HasDefault,
HasParents,
HasResolver,
HasReadonly,
HasDelete,
HasSuccess,
>
{
fn default() -> Self {
Self::new("")
}
}
impl<
HasDefault: IsProvided,
HasReadonly,
HasDelete,
HasSuccess,
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions>,
> BuildableFieldConfig<I, O, CtxOptions, ErrorSanitizer>
for DependentFieldBuilder<
T,
I,
O,
CtxOptions,
ErrorSanitizer,
HasDefault,
Yes,
Yes,
HasReadonly,
HasDelete,
HasSuccess,
>
{
fn build(self) -> InternalFieldConfig<I, O, CtxOptions, ErrorSanitizer> {
FieldConfig {
name: self.name,
field_type: FieldType::Dependent,
default: self.default,
depends_on: self.depends_on,
resolver: self.resolver,
ignore_update: self.ignore_update,
on_delete_fns: self.on_delete_fns,
on_success_fns: self.on_success_fns,
..Default::default()
}
}
}
impl<
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions>,
> DependentFieldBuilder<T, I, O, CtxOptions, ErrorSanitizer>
{
pub fn default(
self,
value: T,
) -> DependentFieldBuilder<T, I, O, CtxOptions, ErrorSanitizer, Yes> {
DependentFieldBuilder {
name: self.name,
default: Some(DefaultValue::Static(erase_value(value))),
..Default::default()
}
}
pub fn default_fn<F>(
self,
default_fn: F,
) -> DependentFieldBuilder<T, I, O, CtxOptions, ErrorSanitizer, YesComputed>
where
F: IntoDefaultValueResolver<T, I, CtxOptions>,
{
DependentFieldBuilder {
name: self.name,
default: Some(DefaultValue::Func(default_fn.into_uniform())),
..Default::default()
}
}
}
impl<
HasDefault: IsProvided,
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions>,
> DependentFieldBuilder<T, I, O, CtxOptions, ErrorSanitizer, HasDefault>
{
pub fn depends_on<const N: usize>(
self,
fields: [&'static str; N],
) -> DependentFieldBuilder<T, I, O, CtxOptions, ErrorSanitizer, HasDefault, Yes> {
DependentFieldBuilder {
name: self.name,
default: self.default,
depends_on: Some(Vec::from(fields)),
..Default::default()
}
}
}
impl<
HasDefault: IsProvided,
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions>,
> DependentFieldBuilder<T, I, O, CtxOptions, ErrorSanitizer, HasDefault, Yes>
{
pub fn resolve<R>(
self,
resolver: R,
) -> DependentFieldBuilder<T, I, O, CtxOptions, ErrorSanitizer, HasDefault, Yes, Yes>
where
R: IntoUniformResolver<T, I, O, CtxOptions>,
{
DependentFieldBuilder {
name: self.name,
default: self.default,
depends_on: self.depends_on,
resolver: Some(resolver.into_uniform()),
..Default::default()
}
}
}
impl<
HasDefault: IsProvidedButNotComputed,
HasDelete,
HasSuccess,
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions>,
>
DependentFieldBuilder<
T,
I,
O,
CtxOptions,
ErrorSanitizer,
HasDefault,
Yes,
Yes,
No,
HasDelete,
HasSuccess,
>
{
pub fn readonly(
self,
) -> DependentFieldBuilder<
T,
I,
O,
CtxOptions,
ErrorSanitizer,
HasDefault,
Yes,
Yes,
Yes,
HasDelete,
HasSuccess,
> {
DependentFieldBuilder {
name: self.name,
default: self.default,
depends_on: self.depends_on,
resolver: self.resolver,
ignore_update: Some(IsFieldProvisionEnabled::Readonly),
..Default::default()
}
}
}
impl<
HasDefault: IsProvided,
HasReadonly,
HasDelete,
HasSuccess,
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions>,
>
DependentFieldBuilder<
T,
I,
O,
CtxOptions,
ErrorSanitizer,
HasDefault,
Yes,
Yes,
HasReadonly,
HasDelete,
HasSuccess,
>
{
pub fn on_delete<H>(
self,
handler: H,
) -> DependentFieldBuilder<
T,
I,
O,
CtxOptions,
ErrorSanitizer,
HasDefault,
Yes,
Yes,
HasReadonly,
Yes,
HasSuccess,
>
where
H: IntoDeleteHandler<O, CtxOptions>,
{
let h = handler.into_handler();
DependentFieldBuilder {
name: self.name,
default: self.default,
depends_on: self.depends_on,
resolver: self.resolver,
ignore_update: self.ignore_update,
on_delete_fns: Some(match self.on_delete_fns {
Some(hs) => {
let mut v = hs;
v.push(h);
v
}
_ => vec![h],
}),
on_success_fns: self.on_success_fns,
..Default::default()
}
}
}
impl<
HasDefault: IsProvided,
HasReadonly,
HasDelete,
HasSuccess,
T: FieldValue,
I: IvoStruct,
O: IvoStruct,
CtxOptions,
ErrorSanitizer: IvoErrorSanitizer<CtxOptions>,
>
DependentFieldBuilder<
T,
I,
O,
CtxOptions,
ErrorSanitizer,
HasDefault,
Yes,
Yes,
HasReadonly,
HasDelete,
HasSuccess,
>
{
pub fn on_success<H>(
self,
handler: H,
) -> DependentFieldBuilder<
T,
I,
O,
CtxOptions,
ErrorSanitizer,
HasDefault,
Yes,
Yes,
HasReadonly,
HasDelete,
Yes,
>
where
H: IntoSuccessHandler<I, O, CtxOptions>,
{
let h = handler.into_handler();
DependentFieldBuilder {
name: self.name,
default: self.default,
depends_on: self.depends_on,
resolver: self.resolver,
ignore_update: self.ignore_update,
on_delete_fns: self.on_delete_fns,
on_success_fns: Some(match self.on_success_fns {
Some(hs) => {
let mut v = hs;
v.push(h);
v
}
_ => vec![h],
}),
..Default::default()
}
}
}