laminar_connectors/fpml/
limits.rs1use crate::config::ConnectorConfig;
4use crate::error::ConnectorError;
5
6const MAX_DOCUMENT_BYTES_CEILING: usize = 256 * 1024 * 1024;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct Limits {
12 pub max_document_bytes: usize,
14 pub max_depth: usize,
16 pub max_elements: usize,
18 pub max_attributes_per_element: usize,
20 pub max_text_bytes: usize,
22 pub max_namespace_declarations: usize,
24 pub max_ids: usize,
26 pub max_references: usize,
28 pub max_rows: usize,
30 pub max_staged_bytes: usize,
32}
33
34impl Default for Limits {
35 fn default() -> Self {
36 Self {
37 max_document_bytes: 16 * 1024 * 1024,
38 max_depth: 64,
39 max_elements: 250_000,
40 max_attributes_per_element: 32,
41 max_text_bytes: 1024 * 1024,
42 max_namespace_declarations: 64,
43 max_ids: 100_000,
44 max_references: 100_000,
45 max_rows: 10_000,
46 max_staged_bytes: 64 * 1024 * 1024,
47 }
48 }
49}
50
51impl Limits {
52 pub fn from_config(config: &ConnectorConfig) -> Result<Self, ConnectorError> {
58 let defaults = Self::default();
59 let limits = Self {
60 max_document_bytes: bound(
61 config,
62 "fpml.max.document.bytes",
63 defaults.max_document_bytes,
64 )?,
65 max_depth: bound(config, "fpml.max.depth", defaults.max_depth)?,
66 max_elements: bound(config, "fpml.max.elements", defaults.max_elements)?,
67 max_attributes_per_element: bound(
68 config,
69 "fpml.max.attributes.per.element",
70 defaults.max_attributes_per_element,
71 )?,
72 max_text_bytes: bound(config, "fpml.max.text.bytes", defaults.max_text_bytes)?,
73 max_namespace_declarations: bound(
74 config,
75 "fpml.max.namespace.declarations",
76 defaults.max_namespace_declarations,
77 )?,
78 max_ids: bound(config, "fpml.max.ids", defaults.max_ids)?,
79 max_references: bound(config, "fpml.max.references", defaults.max_references)?,
80 max_rows: bound(config, "fpml.max.rows", defaults.max_rows)?,
81 max_staged_bytes: bound(config, "fpml.max.staged.bytes", defaults.max_staged_bytes)?,
82 };
83 if limits.max_document_bytes > MAX_DOCUMENT_BYTES_CEILING {
84 return Err(ConnectorError::ConfigurationError(format!(
85 "'fpml.max.document.bytes' must not exceed {MAX_DOCUMENT_BYTES_CEILING}"
86 )));
87 }
88 Ok(limits)
89 }
90}
91
92fn bound(config: &ConnectorConfig, key: &str, default: usize) -> Result<usize, ConnectorError> {
93 let value = config.get_parsed::<usize>(key)?.unwrap_or(default);
94 if value == 0 {
95 return Err(ConnectorError::ConfigurationError(format!(
96 "'{key}' must be greater than zero"
97 )));
98 }
99 Ok(value)
100}