greentic_component/
limits.rs

1use serde::{Deserialize, Serialize};
2use serde_with::rust::double_option;
3use thiserror::Error;
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
6pub struct Limits {
7    pub memory_mb: u32,
8    pub wall_time_ms: u64,
9    #[serde(default)]
10    pub fuel: Option<u64>,
11    #[serde(default)]
12    pub files: Option<u32>,
13}
14
15impl Limits {
16    pub fn validate(&self) -> Result<(), LimitError> {
17        if self.memory_mb == 0 {
18            return Err(LimitError::NonZero {
19                field: "memory_mb",
20                value: self.memory_mb as u128,
21            });
22        }
23        if self.wall_time_ms == 0 {
24            return Err(LimitError::NonZero {
25                field: "wall_time_ms",
26                value: self.wall_time_ms as u128,
27            });
28        }
29        Ok(())
30    }
31}
32
33#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
34pub struct LimitOverrides {
35    #[serde(default)]
36    pub memory_mb: Option<u32>,
37    #[serde(default)]
38    pub wall_time_ms: Option<u64>,
39    #[serde(default, with = "double_option")]
40    pub fuel: Option<Option<u64>>,
41    #[serde(default, with = "double_option")]
42    pub files: Option<Option<u32>>,
43}
44
45pub fn defaults_dev() -> Limits {
46    Limits {
47        memory_mb: 256,
48        wall_time_ms: 30_000,
49        fuel: Some(50_000),
50        files: Some(128),
51    }
52}
53
54pub fn merge(user: Option<&LimitOverrides>, defaults: &Limits) -> Limits {
55    let mut merged = defaults.clone();
56    if let Some(overrides) = user {
57        if let Some(memory_mb) = overrides.memory_mb {
58            merged.memory_mb = memory_mb;
59        }
60        if let Some(wall_time_ms) = overrides.wall_time_ms {
61            merged.wall_time_ms = wall_time_ms;
62        }
63        if let Some(fuel) = overrides.fuel {
64            merged.fuel = fuel;
65        }
66        if let Some(files) = overrides.files {
67            merged.files = files;
68        }
69    }
70    merged
71}
72
73#[derive(Debug, Clone, PartialEq, Eq, Error)]
74pub enum LimitError {
75    #[error("limit `{field}` must be greater than zero (got {value})")]
76    NonZero { field: &'static str, value: u128 },
77}