use derive_builder::Builder;
use derive_variants::EnumVariants;
use partial_derive2::{Diff, MaybeNone, Partial, PartialDiff};
use serde::{Deserialize, Serialize};
use strum::{Display, EnumString};
use typeshare::typeshare;
use super::{
config::{DockerRegistry, GitProvider},
resource::{AddFilters, Resource, ResourceListItem, ResourceQuery},
MergePartial,
};
#[typeshare]
pub type Builder = Resource<BuilderConfig, ()>;
#[typeshare]
pub type BuilderListItem = ResourceListItem<BuilderListItemInfo>;
#[typeshare(serialized_as = "Partial<BuilderConfig>")]
pub type _PartialBuilderConfig = PartialBuilderConfig;
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BuilderListItemInfo {
pub builder_type: String,
pub instance_type: Option<String>,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, EnumVariants)]
#[variant_derive(
Serialize,
Deserialize,
Debug,
Clone,
Copy,
Display,
EnumString
)]
#[serde(tag = "type", content = "params")]
#[allow(clippy::large_enum_variant)]
pub enum BuilderConfig {
Server(ServerBuilderConfig),
Aws(AwsBuilderConfig),
}
impl Default for BuilderConfig {
fn default() -> Self {
Self::Aws(Default::default())
}
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, EnumVariants)]
#[variant_derive(
Serialize,
Deserialize,
Debug,
Clone,
Copy,
Display,
EnumString
)]
#[serde(tag = "type", content = "params")]
#[allow(clippy::large_enum_variant)]
pub enum PartialBuilderConfig {
Server(_PartialServerBuilderConfig),
Aws(_PartialAwsBuilderConfig),
}
impl Default for PartialBuilderConfig {
fn default() -> Self {
Self::Aws(Default::default())
}
}
impl MaybeNone for PartialBuilderConfig {
fn is_none(&self) -> bool {
match self {
PartialBuilderConfig::Server(config) => config.is_none(),
PartialBuilderConfig::Aws(config) => config.is_none(),
}
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BuilderConfigDiff {
Server(ServerBuilderConfigDiff),
Aws(AwsBuilderConfigDiff),
}
impl From<BuilderConfigDiff> for PartialBuilderConfig {
fn from(value: BuilderConfigDiff) -> Self {
match value {
BuilderConfigDiff::Server(diff) => {
PartialBuilderConfig::Server(diff.into())
}
BuilderConfigDiff::Aws(diff) => {
PartialBuilderConfig::Aws(diff.into())
}
}
}
}
impl Diff for BuilderConfigDiff {
fn iter_field_diffs(
&self,
) -> impl Iterator<Item = partial_derive2::FieldDiff> {
match self {
BuilderConfigDiff::Server(diff) => {
diff.iter_field_diffs().collect::<Vec<_>>().into_iter()
}
BuilderConfigDiff::Aws(diff) => {
diff.iter_field_diffs().collect::<Vec<_>>().into_iter()
}
}
}
}
impl PartialDiff<PartialBuilderConfig, BuilderConfigDiff>
for BuilderConfig
{
fn partial_diff(
&self,
partial: PartialBuilderConfig,
) -> BuilderConfigDiff {
match self {
BuilderConfig::Server(original) => match partial {
PartialBuilderConfig::Server(partial) => {
BuilderConfigDiff::Server(original.partial_diff(partial))
}
PartialBuilderConfig::Aws(partial) => {
let default = AwsBuilderConfig::default();
BuilderConfigDiff::Aws(default.partial_diff(partial))
}
},
BuilderConfig::Aws(original) => match partial {
PartialBuilderConfig::Aws(partial) => {
BuilderConfigDiff::Aws(original.partial_diff(partial))
}
PartialBuilderConfig::Server(partial) => {
let default = ServerBuilderConfig::default();
BuilderConfigDiff::Server(default.partial_diff(partial))
}
},
}
}
}
impl MaybeNone for BuilderConfigDiff {
fn is_none(&self) -> bool {
match self {
BuilderConfigDiff::Server(config) => config.is_none(),
BuilderConfigDiff::Aws(config) => config.is_none(),
}
}
}
impl From<PartialBuilderConfig> for BuilderConfig {
fn from(value: PartialBuilderConfig) -> BuilderConfig {
match value {
PartialBuilderConfig::Server(server) => {
BuilderConfig::Server(server.into())
}
PartialBuilderConfig::Aws(builder) => {
BuilderConfig::Aws(builder.into())
}
}
}
}
impl From<BuilderConfig> for PartialBuilderConfig {
fn from(value: BuilderConfig) -> Self {
match value {
BuilderConfig::Server(config) => {
PartialBuilderConfig::Server(config.into())
}
BuilderConfig::Aws(config) => {
PartialBuilderConfig::Aws(config.into())
}
}
}
}
impl MergePartial for BuilderConfig {
type Partial = PartialBuilderConfig;
fn merge_partial(
self,
partial: PartialBuilderConfig,
) -> BuilderConfig {
match partial {
PartialBuilderConfig::Server(partial) => match self {
BuilderConfig::Server(config) => {
let config = ServerBuilderConfig {
server_id: partial.server_id.unwrap_or(config.server_id),
};
BuilderConfig::Server(config)
}
_ => BuilderConfig::Server(partial.into()),
},
PartialBuilderConfig::Aws(partial) => match self {
BuilderConfig::Aws(config) => {
let config = AwsBuilderConfig {
region: partial.region.unwrap_or(config.region),
instance_type: partial
.instance_type
.unwrap_or(config.instance_type),
volume_gb: partial.volume_gb.unwrap_or(config.volume_gb),
ami_id: partial.ami_id.unwrap_or(config.ami_id),
subnet_id: partial.subnet_id.unwrap_or(config.subnet_id),
security_group_ids: partial
.security_group_ids
.unwrap_or(config.security_group_ids),
key_pair_name: partial
.key_pair_name
.unwrap_or(config.key_pair_name),
assign_public_ip: partial
.assign_public_ip
.unwrap_or(config.assign_public_ip),
use_public_ip: partial
.use_public_ip
.unwrap_or(config.use_public_ip),
port: partial.port.unwrap_or(config.port),
git_providers: partial
.git_providers
.unwrap_or(config.git_providers),
docker_registries: partial
.docker_registries
.unwrap_or(config.docker_registries),
secrets: partial.secrets.unwrap_or(config.secrets),
};
BuilderConfig::Aws(config)
}
_ => BuilderConfig::Aws(partial.into()),
},
}
}
}
#[typeshare(serialized_as = "Partial<ServerBuilderConfig>")]
pub type _PartialServerBuilderConfig = PartialServerBuilderConfig;
#[typeshare]
#[derive(
Serialize, Deserialize, Debug, Clone, Default, Builder, Partial,
)]
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
#[partial(skip_serializing_none, from, diff)]
pub struct ServerBuilderConfig {
#[serde(alias = "server")]
#[partial_attr(serde(alias = "server"))]
pub server_id: String,
}
#[typeshare(serialized_as = "Partial<AwsBuilderConfig>")]
pub type _PartialAwsBuilderConfig = PartialAwsBuilderConfig;
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize, Builder, Partial)]
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
#[partial(skip_serializing_none, from, diff)]
pub struct AwsBuilderConfig {
#[serde(default = "aws_default_region")]
#[builder(default = "aws_default_region()")]
#[partial_default(aws_default_region())]
pub region: String,
#[serde(default = "aws_default_instance_type")]
#[builder(default = "aws_default_instance_type()")]
#[partial_default(aws_default_instance_type())]
pub instance_type: String,
#[serde(default = "aws_default_volume_gb")]
#[builder(default = "aws_default_volume_gb()")]
#[partial_default(aws_default_volume_gb())]
pub volume_gb: i32,
#[serde(default = "default_port")]
#[builder(default = "default_port()")]
#[partial_default(default_port())]
pub port: i32,
pub ami_id: String,
pub subnet_id: String,
pub key_pair_name: String,
pub assign_public_ip: bool,
pub use_public_ip: bool,
pub security_group_ids: Vec<String>,
#[serde(default)]
pub git_providers: Vec<GitProvider>,
#[serde(default)]
pub docker_registries: Vec<DockerRegistry>,
#[serde(default)]
pub secrets: Vec<String>,
}
impl Default for AwsBuilderConfig {
fn default() -> Self {
Self {
region: aws_default_region(),
instance_type: aws_default_instance_type(),
volume_gb: aws_default_volume_gb(),
port: default_port(),
ami_id: Default::default(),
subnet_id: Default::default(),
security_group_ids: Default::default(),
key_pair_name: Default::default(),
assign_public_ip: false,
use_public_ip: false,
git_providers: Default::default(),
docker_registries: Default::default(),
secrets: Default::default(),
}
}
}
impl AwsBuilderConfig {
pub fn builder() -> AwsBuilderConfigBuilder {
AwsBuilderConfigBuilder::default()
}
}
fn aws_default_region() -> String {
String::from("us-east-1")
}
fn aws_default_instance_type() -> String {
String::from("c5.2xlarge")
}
fn aws_default_volume_gb() -> i32 {
20
}
fn default_port() -> i32 {
8120
}
#[typeshare]
pub type BuilderQuery = ResourceQuery<BuilderQuerySpecifics>;
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct BuilderQuerySpecifics {}
impl AddFilters for BuilderQuerySpecifics {}