appcore_filemaker/
limits.rs1use serde::{Deserialize, Serialize};
12
13use crate::{ErrorCode, FileMakerError, Result};
14
15#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
17#[serde(default, deny_unknown_fields)]
18pub struct ResourceLimits {
19 pub max_template_bytes: usize,
21 pub max_include_bytes: usize,
23 pub max_include_depth: usize,
25 pub max_elements: usize,
27 pub max_path_commands: usize,
29 pub max_pages: usize,
31 pub max_text_bytes: usize,
33 pub max_asset_bytes: usize,
35 pub max_pixels: u64,
37 pub max_reflows: usize,
39 pub max_collision_comparisons: usize,
41 pub max_expression_steps: usize,
43 pub max_patch_operations: usize,
45 pub max_preflight_comparisons: usize,
48 pub max_rows: u64,
50 pub max_output_bytes: usize,
52}
53
54impl Default for ResourceLimits {
55 fn default() -> Self {
56 Self {
57 max_template_bytes: 4 * 1024 * 1024,
58 max_include_bytes: 16 * 1024 * 1024,
59 max_include_depth: 16,
60 max_elements: 100_000,
61 max_path_commands: 1_000_000,
62 max_pages: 10_000,
63 max_text_bytes: 4 * 1024 * 1024,
64 max_asset_bytes: 256 * 1024 * 1024,
65 max_pixels: 100_000_000,
66 max_reflows: 128,
67 max_collision_comparisons: 1_000_000,
68 max_expression_steps: 10_000,
69 max_patch_operations: 10_000,
70 max_preflight_comparisons: 1_000_000,
71 max_rows: 10_000_000,
72 max_output_bytes: 512 * 1024 * 1024,
73 }
74 }
75}
76
77impl ResourceLimits {
78 pub fn validate(&self) -> Result<()> {
80 let all_nonzero = self.max_template_bytes > 0
81 && self.max_include_bytes > 0
82 && self.max_include_depth > 0
83 && self.max_elements > 0
84 && self.max_path_commands > 0
85 && self.max_pages > 0
86 && self.max_text_bytes > 0
87 && self.max_asset_bytes > 0
88 && self.max_pixels > 0
89 && self.max_reflows > 0
90 && self.max_collision_comparisons > 0
91 && self.max_expression_steps > 0
92 && self.max_patch_operations > 0
93 && self.max_preflight_comparisons > 0
94 && self.max_rows > 0
95 && self.max_output_bytes > 0;
96 if !all_nonzero {
97 return Err(FileMakerError::new(
98 ErrorCode::LimitExceeded,
99 "resource limits must be non-zero",
100 ));
101 }
102 Ok(())
103 }
104
105 #[allow(dead_code)]
107 pub(crate) fn check(name: &'static str, observed: usize, limit: usize) -> Result<()> {
108 if observed > limit {
109 return Err(FileMakerError::new(
110 ErrorCode::LimitExceeded,
111 format!("{name} is {observed}; limit is {limit}"),
112 ));
113 }
114 Ok(())
115 }
116}