#![doc = "Generated transport-independent contract objects."]
use std::error::Error as StdError;
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use spiral_contract::error::{ErrorEnvelope, ServiceError};
use spiral_contract::safelong::SafeUnsignedLong;
use spiral_contract::strict::{DeserializeStrict, Strict};
use uuid::Uuid;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ManagedWorkerPhase {
Disabled,
Idle,
Active,
ScalingDown,
ScalingUp,
Provisioning,
Degraded,
Unknown(String),
}
impl Serialize for ManagedWorkerPhase {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(match self {
Self::Disabled => "disabled",
Self::Idle => "idle",
Self::Active => "active",
Self::ScalingDown => "scaling_down",
Self::ScalingUp => "scaling_up",
Self::Provisioning => "provisioning",
Self::Degraded => "degraded",
Self::Unknown(value) => value,
})
}
}
impl<'de> Deserialize<'de> for ManagedWorkerPhase {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(match String::deserialize(deserializer)?.as_str() {
"disabled" => Self::Disabled,
"idle" => Self::Idle,
"active" => Self::Active,
"scaling_down" => Self::ScalingDown,
"scaling_up" => Self::ScalingUp,
"provisioning" => Self::Provisioning,
"degraded" => Self::Degraded,
value => Self::Unknown(value.to_owned()),
})
}
}
impl<'de> DeserializeStrict<'de> for ManagedWorkerPhase {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
enum __Known {
#[serde(rename = "disabled")]
Disabled,
#[serde(rename = "idle")]
Idle,
#[serde(rename = "active")]
Active,
#[serde(rename = "scaling_down")]
ScalingDown,
#[serde(rename = "scaling_up")]
ScalingUp,
#[serde(rename = "provisioning")]
Provisioning,
#[serde(rename = "degraded")]
Degraded,
}
Ok(match __Known::deserialize(deserializer)? {
__Known::Disabled => Self::Disabled,
__Known::Idle => Self::Idle,
__Known::Active => Self::Active,
__Known::ScalingDown => Self::ScalingDown,
__Known::ScalingUp => Self::ScalingUp,
__Known::Provisioning => Self::Provisioning,
__Known::Degraded => Self::Degraded,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ManagedWorkerProviderResponse {
#[serde(rename = "activeWorkers")]
pub active_workers: SafeUnsignedLong,
#[serde(rename = "busyWorkers")]
pub busy_workers: SafeUnsignedLong,
#[serde(rename = "displayName")]
pub display_name: String,
#[serde(rename = "enabled")]
pub enabled: bool,
#[serde(rename = "id")]
pub id: String,
#[serde(rename = "phase")]
pub phase: ManagedWorkerPhase,
#[serde(rename = "workerPoolIds")]
pub worker_pool_ids: Vec<Uuid>,
}
impl<'de> DeserializeStrict<'de> for ManagedWorkerProviderResponse {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "activeWorkers")]
active_workers: Strict<SafeUnsignedLong>,
#[serde(rename = "busyWorkers")]
busy_workers: Strict<SafeUnsignedLong>,
#[serde(rename = "displayName")]
display_name: Strict<String>,
#[serde(rename = "enabled")]
enabled: Strict<bool>,
#[serde(rename = "id")]
id: Strict<String>,
#[serde(rename = "phase")]
phase: Strict<ManagedWorkerPhase>,
#[serde(rename = "workerPoolIds")]
worker_pool_ids: Strict<Vec<Uuid>>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
active_workers: wire.active_workers.0,
busy_workers: wire.busy_workers.0,
display_name: wire.display_name.0,
enabled: wire.enabled.0,
id: wire.id.0,
phase: wire.phase.0,
worker_pool_ids: wire.worker_pool_ids.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ManagedWorkersResponse {
#[serde(rename = "providers")]
pub providers: Vec<ManagedWorkerProviderResponse>,
#[serde(rename = "workloadId")]
pub workload_id: String,
}
impl<'de> DeserializeStrict<'de> for ManagedWorkersResponse {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "providers")]
providers: Strict<Vec<ManagedWorkerProviderResponse>>,
#[serde(rename = "workloadId")]
workload_id: Strict<String>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
providers: wire.providers.0,
workload_id: wire.workload_id.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum WorkersError {
Conflict { reason: String },
InvalidArgument { reason: String },
LimitReached { reason: String },
NotFound { resource: String },
}
impl WorkersError {
pub fn status(&self) -> u16 {
match self {
Self::Conflict { .. } => 409,
Self::InvalidArgument { .. } => 400,
Self::LimitReached { .. } => 412,
Self::NotFound { .. } => 404,
}
}
pub fn envelope(&self, instance: String) -> ErrorEnvelope {
match self {
Self::Conflict { reason } => {
let mut envelope = ErrorEnvelope::new("CONFLICT", "Workers:Conflict", instance);
envelope
.parameters
.insert("reason".into(), reason.to_string());
envelope
}
Self::InvalidArgument { reason } => {
let mut envelope =
ErrorEnvelope::new("INVALID_ARGUMENT", "Workers:InvalidArgument", instance);
envelope
.parameters
.insert("reason".into(), reason.to_string());
envelope
}
Self::LimitReached { reason } => {
let mut envelope =
ErrorEnvelope::new("FAILED_PRECONDITION", "Workers:LimitReached", instance);
envelope
.parameters
.insert("reason".into(), reason.to_string());
envelope
}
Self::NotFound { resource } => {
let mut envelope = ErrorEnvelope::new("NOT_FOUND", "Workers:NotFound", instance);
envelope
.parameters
.insert("resource".into(), resource.to_string());
envelope
}
}
}
pub fn decode_envelope(envelope: &ErrorEnvelope) -> Option<Self> {
if envelope.error_instance_id.len() != 36
|| Uuid::parse_str(&envelope.error_instance_id).is_err()
{
return None;
}
match envelope.error_name.as_str() {
"Workers:Conflict" => {
if envelope.error_code != "CONFLICT" {
return None;
}
let reason = envelope.parameters.get("reason")?.clone();
Some(Self::Conflict { reason })
}
"Workers:InvalidArgument" => {
if envelope.error_code != "INVALID_ARGUMENT" {
return None;
}
let reason = envelope.parameters.get("reason")?.clone();
Some(Self::InvalidArgument { reason })
}
"Workers:LimitReached" => {
if envelope.error_code != "FAILED_PRECONDITION" {
return None;
}
let reason = envelope.parameters.get("reason")?.clone();
Some(Self::LimitReached { reason })
}
"Workers:NotFound" => {
if envelope.error_code != "NOT_FOUND" {
return None;
}
let resource = envelope.parameters.get("resource")?.clone();
Some(Self::NotFound { resource })
}
_ => None,
}
}
}
impl Display for WorkersError {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Conflict { reason } => write!(formatter, "Workers:Conflict (reason: {})", reason),
Self::InvalidArgument { reason } => {
write!(formatter, "Workers:InvalidArgument (reason: {})", reason)
}
Self::LimitReached { reason } => {
write!(formatter, "Workers:LimitReached (reason: {})", reason)
}
Self::NotFound { resource } => {
write!(formatter, "Workers:NotFound (resource: {})", resource)
}
}
}
}
impl StdError for WorkersError {}
impl ServiceError for WorkersError {
fn to_envelope(&self, instance: String) -> ErrorEnvelope {
Self::envelope(self, instance)
}
fn from_envelope(envelope: &ErrorEnvelope) -> Option<Self> {
Self::decode_envelope(envelope)
}
}