cumulus 0.0.6

AWS CloudFormation Template Generator
Documentation
use serde::Serialize;

use crate::skip_serializing_if::SkipSerializingIf;
use crate::Ref;

/// CloudFormation Template Parameter
/// See [AWS CloudFormation Documenation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html)
#[derive(Clone, Debug, Default, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct Parameter {
    #[serde(skip)]
    name: String,
    #[serde(skip_serializing_if = "String::is_empty")]
    allowed_pattern: String,
    #[serde(skip_serializing_if = "Vec::is_empty")]
    allowed_values: Vec<String>,
    #[serde(skip_serializing_if = "String::is_empty")]
    constraint_description: String,
    #[serde(skip_serializing_if = "String::is_empty")]
    default: String,
    #[serde(skip_serializing_if = "String::is_empty")]
    description: String,
    #[serde(skip_serializing_if = "u64::is_zero")]
    max_length: u64,
    #[serde(skip_serializing_if = "u64::is_zero")]
    max_value: u64,
    #[serde(skip_serializing_if = "u64::is_zero")]
    min_length: u64,
    #[serde(skip_serializing_if = "u64::is_zero")]
    min_value: u64,
    #[serde(skip_serializing_if = "bool::is_false")]
    no_echo: bool,
    r#type: DataType,
}

impl Parameter {
    /// Create new `Parameter` of `string` type
    pub fn string(name: impl Into<String>) -> Self {
        let name = name.into();
        let r#type = DataType::String;
        Self {
            name,
            r#type,
            ..<Self as Default>::default()
        }
    }

    /// Create new `Parameter` of `number` type
    pub fn number(name: impl Into<String>) -> Self {
        let name = name.into();
        let r#type = DataType::Number;
        Self {
            name,
            r#type,
            ..<Self as Default>::default()
        }
    }

    pub fn image_id(name: impl Into<String>) -> Self {
        let name = name.into();
        let r#type = DataType::AwsEc2ImageId;
        Self {
            name,
            r#type,
            ..<Self as Default>::default()
        }
    }

    /// Add parameter description
    pub fn description(self, description: impl Into<String>) -> Self {
        let description = description.into();
        Self {
            description,
            ..self
        }
    }

    /// Add parameter default value
    pub fn default(self, default: impl Into<String>) -> Self {
        let default = default.into();
        Self { default, ..self }
    }

    pub fn r#ref(&self) -> Ref {
        Ref::new(&self.name)
    }

    pub(crate) fn name(&self) -> String {
        self.name.clone()
    }
}

#[derive(Clone, Debug, Serialize)]
pub enum DataType {
    String,
    Number,
    #[serde(rename = "AWS::EC2::Image::Id")]
    AwsEc2ImageId,
}

impl Default for DataType {
    fn default() -> Self {
        Self::String
    }
}