use std::fmt;
use serde::{Deserialize, Serialize};
use crate::infra::execution::backend::ExecutionProfileKind;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
#[serde(rename_all = "snake_case")]
pub enum ProjectRuntimeMode {
#[default]
Shared,
Pinned,
Dedicated,
}
impl ProjectRuntimeMode {
pub const fn as_str(self) -> &'static str {
match self {
Self::Shared => "shared",
Self::Pinned => "pinned",
Self::Dedicated => "dedicated",
}
}
}
impl fmt::Display for ProjectRuntimeMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
#[serde(rename_all = "snake_case")]
pub enum ResourceProfile {
Tiny,
#[default]
Small,
Medium,
Large,
Custom,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub struct RuntimeResourceSpec {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cpu_request_millis: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory_request_mb: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cpu_limit_millis: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory_limit_mb: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ephemeral_disk_mb: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub accelerator_count: Option<u16>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ProjectRuntimeProfile {
#[serde(default)]
pub mode: ProjectRuntimeMode,
#[serde(default)]
pub execution: ExecutionProfileKind,
#[serde(default)]
pub resource_profile: ResourceProfile,
#[serde(default = "default_min_replicas")]
pub min_replicas: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_replicas: Option<u32>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub required_tags: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub custom_resources: Option<RuntimeResourceSpec>,
}
const fn default_min_replicas() -> u32 {
1
}
impl Default for ProjectRuntimeProfile {
fn default() -> Self {
Self {
mode: ProjectRuntimeMode::Shared,
execution: ExecutionProfileKind::Resident,
resource_profile: ResourceProfile::Small,
min_replicas: default_min_replicas(),
max_replicas: None,
required_tags: Vec::new(),
custom_resources: None,
}
}
}
impl ProjectRuntimeProfile {
pub fn uses_custom_resources(&self) -> bool {
self.resource_profile == ResourceProfile::Custom && self.custom_resources.is_some()
}
}
#[cfg(test)]
mod tests {
use super::{ProjectRuntimeMode, ProjectRuntimeProfile, ResourceProfile};
use crate::infra::execution::backend::ExecutionProfileKind;
#[test]
fn default_runtime_profile_is_portable() {
let profile = ProjectRuntimeProfile::default();
assert_eq!(profile.mode, ProjectRuntimeMode::Shared);
assert_eq!(profile.execution, ExecutionProfileKind::Resident);
assert_eq!(profile.resource_profile, ResourceProfile::Small);
assert_eq!(profile.min_replicas, 1);
assert!(profile.max_replicas.is_none());
}
}