use std::borrow::Cow;
use serde::{Deserialize, Serialize};
#[cfg(feature = "validation")]
use validator::Validate;
#[cfg(feature = "validation")]
use crate::val_helpr::ValidationResult;
use crate::{compose,
compose::{opt::NoUrl, Confirm},
text};
type Opt<'a> = compose::Opt<'a, text::Plain, NoUrl>;
type OptGroup<'a> = compose::OptGroup<'a, text::Plain, NoUrl>;
type OptOrOptGroup<'a> = compose::OptOrOptGroup<'a, text::Plain, NoUrl>;
#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)]
#[cfg_attr(feature = "validation", derive(Validate))]
pub struct External<'a> {
#[cfg_attr(feature = "validation",
validate(custom = "super::validate::placeholder"))]
placeholder: text::Text,
#[cfg_attr(feature = "validation", validate(length(max = 255)))]
action_id: Cow<'a, str>,
#[serde(skip_serializing_if = "Option::is_none")]
initial_option: Option<OptOrOptGroup<'a>>,
#[serde(skip_serializing_if = "Option::is_none")]
min_query_length: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "validation", validate)]
confirm: Option<Confirm>,
}
impl<'a> External<'a> {
pub fn builder() -> build::ExternalBuilderInit<'a> {
build::ExternalBuilderInit::new()
}
#[cfg(feature = "validation")]
#[cfg_attr(docsrs, doc(cfg(feature = "validation")))]
pub fn validate(&self) -> ValidationResult {
Validate::validate(self)
}
}
pub mod build {
use std::marker::PhantomData;
use super::*;
use crate::{build::*,
elems::select::{multi, select_kind}};
#[allow(non_camel_case_types)]
pub mod method {
#[derive(Copy, Clone, Debug)]
pub struct placeholder;
#[derive(Copy, Clone, Debug)]
pub struct initial_option;
#[derive(Copy, Clone, Debug)]
pub struct action_id;
}
#[derive(Debug)]
pub struct ExternalBuilder<'a, Multi, Placeholder, ActionId, Options> {
placeholder: Option<text::Text>,
action_id: Option<Cow<'a, str>>,
confirm: Option<Confirm>,
initial_option: Option<OptOrOptGroup<'a>>,
initial_options: Option<Cow<'a, [OptOrOptGroup<'a>]>>,
max_selected_items: Option<u32>,
min_query_length: Option<u64>,
state: PhantomData<(Multi, Placeholder, ActionId, Options)>,
}
pub type ExternalBuilderInit<'a> =
ExternalBuilder<'a,
select_kind::Single,
RequiredMethodNotCalled<method::placeholder>,
RequiredMethodNotCalled<method::action_id>,
OptionalMethodNotCalled<method::initial_option>>;
pub type MultiExternalBuilderInit<'a> =
ExternalBuilder<'a,
select_kind::Multi,
RequiredMethodNotCalled<method::placeholder>,
RequiredMethodNotCalled<method::action_id>,
OptionalMethodNotCalled<method::initial_option>>;
impl<'a, M, P, A, O> ExternalBuilder<'a, M, P, A, O> {
pub fn new() -> Self {
Self { placeholder: None,
action_id: None,
initial_option: None,
initial_options: None,
max_selected_items: None,
confirm: None,
min_query_length: None,
state: PhantomData::<_> }
}
fn cast_state<P2, A2, O2>(self) -> ExternalBuilder<'a, M, P2, A2, O2> {
ExternalBuilder { placeholder: self.placeholder,
action_id: self.action_id,
confirm: self.confirm,
initial_option: self.initial_option,
initial_options: self.initial_options,
max_selected_items: self.max_selected_items,
min_query_length: self.min_query_length,
state: PhantomData::<_> }
}
pub fn placeholder(
mut self,
text: impl Into<text::Plain>)
-> ExternalBuilder<'a, M, Set<method::placeholder>, A, O> {
self.placeholder = Some(text.into().into());
self.cast_state()
}
pub fn action_id(
mut self,
text: impl Into<Cow<'a, str>>)
-> ExternalBuilder<'a, M, P, Set<method::action_id>, O> {
self.action_id = Some(text.into());
self.cast_state()
}
pub fn confirm(mut self, confirm: Confirm) -> Self {
self.confirm = Some(confirm);
self
}
pub fn min_query_length(mut self, min: u64) -> Self {
self.min_query_length = Some(min);
self
}
}
impl<'a, P, A, O> ExternalBuilder<'a, select_kind::Multi, P, A, O> {
pub fn max_selected_items(mut self, max: u32) -> Self {
self.max_selected_items = Some(max);
self
}
}
impl<'a, P, A>
ExternalBuilder<'a,
select_kind::Multi,
P,
A,
OptionalMethodNotCalled<method::initial_option>>
{
pub fn initial_options<I>(
mut self,
options: I)
-> ExternalBuilder<'a,
select_kind::Multi,
P,
A,
Set<method::initial_option>>
where I: IntoIterator<Item = Opt<'a>>
{
self.initial_options = Some(options.into_iter()
.map(|o| OptOrOptGroup::<'a>::Opt(o))
.collect());
self.cast_state()
}
pub fn initial_option_groups<I>(
mut self,
option_groups: I)
-> ExternalBuilder<'a,
select_kind::Multi,
P,
A,
Set<method::initial_option>>
where I: IntoIterator<Item = OptGroup<'a>>
{
self.initial_options =
Some(option_groups.into_iter()
.map(|o| OptOrOptGroup::<'a>::OptGroup(o))
.collect());
self.cast_state()
}
}
impl<'a, P, A>
ExternalBuilder<'a,
select_kind::Single,
P,
A,
OptionalMethodNotCalled<method::initial_option>>
{
pub fn initial_option(
mut self,
option: Opt<'a>)
-> ExternalBuilder<'a,
select_kind::Single,
P,
A,
Set<method::initial_option>> {
self.initial_option = Some(OptOrOptGroup::<'a>::Opt(option));
self.cast_state()
}
pub fn initial_option_group(
mut self,
option_group: OptGroup<'a>)
-> ExternalBuilder<'a,
select_kind::Single,
P,
A,
Set<method::initial_option>> {
self.initial_option = Some(OptOrOptGroup::<'a>::OptGroup(option_group));
self.cast_state()
}
}
impl<'a, O>
ExternalBuilder<'a,
select_kind::Single,
Set<method::placeholder>,
Set<method::action_id>,
O>
{
pub fn build(self) -> External<'a> {
External { placeholder: self.placeholder.unwrap(),
action_id: self.action_id.unwrap(),
confirm: self.confirm,
initial_option: self.initial_option,
min_query_length: self.min_query_length }
}
}
impl<'a, O>
ExternalBuilder<'a,
select_kind::Multi,
Set<method::placeholder>,
Set<method::action_id>,
O>
{
pub fn build(self) -> multi::External<'a> {
multi::External { placeholder: self.placeholder.unwrap(),
action_id: self.action_id.unwrap(),
confirm: self.confirm,
initial_options: self.initial_options,
min_query_length: self.min_query_length,
max_selected_items: self.max_selected_items }
}
}
}