greentic-component 0.5.2

High-level component loader and store for Greentic components
Documentation
use serde::{Deserialize, Serialize};
use serde_with::rust::double_option;
use thiserror::Error;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Limits {
    pub memory_mb: u32,
    pub wall_time_ms: u64,
    #[serde(default)]
    pub fuel: Option<u64>,
    #[serde(default)]
    pub files: Option<u32>,
}

impl Limits {
    pub fn validate(&self) -> Result<(), LimitError> {
        if self.memory_mb == 0 {
            return Err(LimitError::NonZero {
                field: "memory_mb",
                value: self.memory_mb as u128,
            });
        }
        if self.wall_time_ms == 0 {
            return Err(LimitError::NonZero {
                field: "wall_time_ms",
                value: self.wall_time_ms as u128,
            });
        }
        Ok(())
    }
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct LimitOverrides {
    #[serde(default)]
    pub memory_mb: Option<u32>,
    #[serde(default)]
    pub wall_time_ms: Option<u64>,
    #[serde(default, with = "double_option")]
    pub fuel: Option<Option<u64>>,
    #[serde(default, with = "double_option")]
    pub files: Option<Option<u32>>,
}

pub fn defaults_dev() -> Limits {
    Limits {
        memory_mb: 256,
        wall_time_ms: 30_000,
        fuel: Some(50_000),
        files: Some(128),
    }
}

pub fn merge(user: Option<&LimitOverrides>, defaults: &Limits) -> Limits {
    let mut merged = defaults.clone();
    if let Some(overrides) = user {
        if let Some(memory_mb) = overrides.memory_mb {
            merged.memory_mb = memory_mb;
        }
        if let Some(wall_time_ms) = overrides.wall_time_ms {
            merged.wall_time_ms = wall_time_ms;
        }
        if let Some(fuel) = overrides.fuel {
            merged.fuel = fuel;
        }
        if let Some(files) = overrides.files {
            merged.files = files;
        }
    }
    merged
}

#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum LimitError {
    #[error("limit `{field}` must be greater than zero (got {value})")]
    NonZero { field: &'static str, value: u128 },
}