use std::{borrow::Cow, convert::TryFrom};
use serde::{Deserialize, Serialize};
#[cfg(feature = "validation")]
use validator::Validate;
#[cfg(feature = "validation")]
use crate::val_helpr::*;
use crate::{convert,
elems::{select,
BlockElement,
Button,
Checkboxes,
DatePicker,
Overflow,
Radio,
TextInput}};
#[derive(Clone, Debug, Default, Deserialize, Hash, PartialEq, Serialize)]
#[cfg_attr(feature = "validation", derive(Validate))]
pub struct Actions<'a> {
#[cfg_attr(feature = "validation", validate(length(max = 5)))]
elements: Vec<SupportedElement<'a>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "validation",
validate(custom = "super::validate_block_id"))]
block_id: Option<Cow<'a, str>>,
}
impl<'a> Actions<'a> {
pub fn builder() -> build::ActionsBuilderInit<'a> {
build::ActionsBuilderInit::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::*;
#[allow(non_camel_case_types)]
pub mod method {
#[derive(Clone, Copy, Debug)]
pub struct elements;
}
pub type ActionsBuilderInit<'a> =
ActionsBuilder<'a, RequiredMethodNotCalled<method::elements>>;
#[derive(Debug)]
pub struct ActionsBuilder<'a, Elements> {
elements: Option<Vec<SupportedElement<'a>>>,
block_id: Option<Cow<'a, str>>,
state: PhantomData<Elements>,
}
impl<'a, E> ActionsBuilder<'a, E> {
pub fn new() -> Self {
Self { elements: None,
block_id: None,
state: PhantomData::<_> }
}
pub fn element<El>(self,
element: El)
-> ActionsBuilder<'a, Set<method::elements>>
where El: Into<SupportedElement<'a>>
{
let mut elements = self.elements.unwrap_or_default();
elements.push(element.into());
ActionsBuilder { block_id: self.block_id,
elements: Some(elements),
state: PhantomData::<_> }
}
#[cfg(feature = "blox")]
#[cfg_attr(docsrs, doc(cfg(feature = "blox")))]
pub fn child<El>(self,
element: El)
-> ActionsBuilder<'a, Set<method::elements>>
where El: Into<SupportedElement<'a>>
{
self.element(element)
}
pub fn block_id<S>(mut self, block_id: S) -> Self
where S: Into<Cow<'a, str>>
{
self.block_id = Some(block_id.into());
self
}
}
impl<'a> ActionsBuilder<'a, Set<method::elements>> {
pub fn build(self) -> Actions<'a> {
Actions { elements: self.elements.unwrap(),
block_id: self.block_id }
}
}
}
#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)]
pub struct SupportedElement<'a>(BlockElement<'a>);
impl<'a> TryFrom<BlockElement<'a>> for self::SupportedElement<'a> {
type Error = super::UnsupportedElement<'a>;
fn try_from(el: BlockElement<'a>) -> Result<Self, Self::Error> {
use BlockElement as El;
let unsupported = |el| super::UnsupportedElement { context:
format!("{}::Actions",
module_path!()),
element: el };
match el {
| El::SelectPublicChannel(_)
| El::SelectConversation(_)
| El::SelectExternal(_)
| El::SelectStatic(_)
| El::SelectUser(_)
| El::Overflow(_)
| El::RadioButtons(_)
| El::Button(_)
| El::TextInput(_)
| El::Checkboxes(_)
| El::DatePicker(_) => Ok(SupportedElement(el)),
| _ => Err(unsupported(el)),
}
}
}
convert!(impl<'a> From<select::PublicChannel<'a>> for self::SupportedElement<'a> => |s| self::SupportedElement(BlockElement::from(s)));
convert!(impl<'a> From<select::Conversation<'a>> for self::SupportedElement<'a> => |s| self::SupportedElement(BlockElement::from(s)));
convert!(impl<'a> From<select::User<'a>> for self::SupportedElement<'a> => |s| self::SupportedElement(BlockElement::from(s)));
convert!(impl<'a> From<select::External<'a>> for self::SupportedElement<'a> => |s| self::SupportedElement(BlockElement::from(s)));
convert!(impl<'a> From<select::Static<'a>> for self::SupportedElement<'a> => |s| self::SupportedElement(BlockElement::from(s)));
convert!(impl<'a> From<Button<'a>> for self::SupportedElement<'a> => |b| self::SupportedElement(BlockElement::from(b)));
convert!(impl<'a> From<Radio<'a>> for self::SupportedElement<'a> => |b| self::SupportedElement(BlockElement::from(b)));
convert!(impl<'a> From<TextInput<'a>> for self::SupportedElement<'a> => |t| self::SupportedElement(BlockElement::from(t)));
convert!(impl<'a> From<DatePicker<'a>> for self::SupportedElement<'a> => |t| self::SupportedElement(BlockElement::from(t)));
convert!(impl<'a> From<Checkboxes<'a>> for self::SupportedElement<'a> => |t| self::SupportedElement(BlockElement::from(t)));
convert!(impl<'a> From<Overflow<'a>> for self::SupportedElement<'a> => |t| self::SupportedElement(BlockElement::from(t)));