use crate::chain::{Address, Chain};
use crate::item_hash::ItemHash;
use crate::message::execution::environment::{HostRequirements, MachineResources};
use crate::message::execution::volume::MachineVolume;
use serde::{Deserialize, Deserializer, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Encoding {
Plain,
Zip,
Squashfs,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum PaymentType {
Hold,
Superfluid,
Credit,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Payment {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub chain: Option<Chain>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub receiver: Option<Address>,
#[serde(rename = "type")]
pub payment_type: PaymentType,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Interface {
Asgi,
Binary,
}
fn deserialize_metadata_tolerant<'de, D>(
deserializer: D,
) -> Result<Option<HashMap<String, serde_json::Value>>, D::Error>
where
D: Deserializer<'de>,
{
use serde_json::Value;
let value = Option::<Value>::deserialize(deserializer)?;
match value {
None => Ok(None),
Some(Value::Object(map)) => Ok(Some(map.into_iter().collect())),
Some(Value::Array(arr)) if arr.is_empty() => {
Ok(Some(HashMap::new()))
}
Some(other) => Err(serde::de::Error::custom(format!(
"expected object or empty array for metadata, got {}",
other
))),
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub struct ExecutableContent {
pub allow_amend: bool,
#[serde(
default,
deserialize_with = "deserialize_metadata_tolerant",
skip_serializing_if = "Option::is_none"
)]
pub metadata: Option<HashMap<String, serde_json::Value>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub variables: Option<HashMap<String, String>>,
pub resources: MachineResources,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub payment: Option<Payment>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub requirements: Option<HostRequirements>,
#[serde(default)]
pub volumes: Vec<MachineVolume>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub replaces: Option<ItemHash>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub authorized_keys: Option<Vec<String>>,
}