Skip to main content

entrenar/efficiency/platform/
budget.rs

1//! WASM deployment budget constraints and violations.
2
3use serde::{Deserialize, Serialize};
4
5/// Maximum startup latency for mobile web targets (milliseconds)
6const MOBILE_MAX_STARTUP_MS: u64 = 200;
7/// Default maximum startup latency for WASM deployment (milliseconds)
8const DEFAULT_MAX_STARTUP_MS: u64 = 500;
9
10/// WASM deployment budget constraints
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct WasmBudget {
13    /// Maximum binary size in bytes (default: 5 MB)
14    pub max_binary_size: u64,
15    /// Maximum startup latency in milliseconds (default: 500 ms)
16    pub max_startup_ms: u64,
17    /// Maximum memory usage in bytes (default: 256 MB)
18    pub max_memory_bytes: u64,
19}
20
21impl WasmBudget {
22    /// Create new WASM budget
23    pub fn new(max_binary_size: u64, max_startup_ms: u64, max_memory_bytes: u64) -> Self {
24        Self { max_binary_size, max_startup_ms, max_memory_bytes }
25    }
26
27    /// Create a strict budget for mobile web
28    pub fn mobile() -> Self {
29        Self {
30            max_binary_size: 2 * 1024 * 1024, // 2 MB
31            max_startup_ms: MOBILE_MAX_STARTUP_MS,
32            max_memory_bytes: 128 * 1024 * 1024, // 128 MB
33        }
34    }
35
36    /// Create a standard budget for desktop web
37    pub fn desktop() -> Self {
38        Self {
39            max_binary_size: 10 * 1024 * 1024,   // 10 MB
40            max_startup_ms: 1000,                // 1 second
41            max_memory_bytes: 512 * 1024 * 1024, // 512 MB
42        }
43    }
44
45    /// Create a relaxed budget for embedded/IoT
46    pub fn embedded() -> Self {
47        Self {
48            max_binary_size: 1024 * 1024,       // 1 MB
49            max_startup_ms: 100,                // 100 ms
50            max_memory_bytes: 64 * 1024 * 1024, // 64 MB
51        }
52    }
53
54    /// Get budget sizes in MB
55    pub fn sizes_mb(&self) -> (f64, f64) {
56        (
57            self.max_binary_size as f64 / (1024.0 * 1024.0),
58            self.max_memory_bytes as f64 / (1024.0 * 1024.0),
59        )
60    }
61}
62
63impl Default for WasmBudget {
64    fn default() -> Self {
65        Self {
66            max_binary_size: 5 * 1024 * 1024, // 5 MB
67            max_startup_ms: DEFAULT_MAX_STARTUP_MS,
68            max_memory_bytes: 256 * 1024 * 1024, // 256 MB
69        }
70    }
71}
72
73/// Budget violation details
74#[derive(Debug, Clone, PartialEq)]
75pub enum BudgetViolation {
76    /// Binary size exceeds limit
77    BinarySize { actual: u64, limit: u64 },
78    /// Startup latency exceeds limit
79    StartupLatency { actual: u64, limit: u64 },
80    /// Memory footprint exceeds limit
81    MemoryFootprint { actual: u64, limit: u64 },
82}
83
84impl std::fmt::Display for BudgetViolation {
85    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86        match self {
87            Self::BinarySize { actual, limit } => {
88                write!(
89                    f,
90                    "Binary size {} MB exceeds {} MB limit",
91                    *actual as f64 / (1024.0 * 1024.0),
92                    *limit as f64 / (1024.0 * 1024.0)
93                )
94            }
95            Self::StartupLatency { actual, limit } => {
96                write!(f, "Startup latency {actual} ms exceeds {limit} ms limit")
97            }
98            Self::MemoryFootprint { actual, limit } => {
99                write!(
100                    f,
101                    "Memory footprint {} MB exceeds {} MB limit",
102                    *actual as f64 / (1024.0 * 1024.0),
103                    *limit as f64 / (1024.0 * 1024.0)
104                )
105            }
106        }
107    }
108}