greentic_component/
limits.rs1use 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}