Skip to main content

icydb_schema/wire/
mod.rs

1//! Native RPC resource policy; IC Wire owns the codec and envelopes.
2
3#[cfg(not(target_family = "wasm"))]
4mod metadata;
5
6use ic_wire::Limits;
7use serde::{Serialize, de::DeserializeOwned};
8
9pub use ic_wire::Error;
10
11/// Maximum admitted payload traversal nodes.
12pub const MAX_NODES: usize = 1_048_576;
13/// Maximum admitted Serde nesting, including endpoint record/container boundaries.
14/// Allows the 64-level schema contract plus enum, collection and reply wrappers.
15pub const MAX_DEPTH: usize = 256;
16/// Browser traversal allowance for bounded interactive views.
17///
18/// Intentionally below native policy; large replies can require smaller pages.
19/// This preserves the existing browser contract; it does not bound JS heap use.
20pub const BROWSER_MAX_NODES: usize = 32_768;
21/// Browser nesting allowance, intentionally below the native schema allowance.
22///
23/// Deep native values remain unsupported by the browser view; callers receive a
24/// limit refusal rather than truncated or partially decoded output.
25pub const BROWSER_MAX_DEPTH: usize = 32;
26
27/// Conservative allocation allowance for decoded native payloads.
28pub const MAX_HEAP_BYTES: usize = 256 * 1024 * 1024;
29/// Maximum public reply envelope bytes.
30pub const MAX_REPLY_BYTES: usize = 3 * 1024 * 1024;
31/// Maximum owned endpoint request envelope bytes.
32pub const MAX_REQUEST_BYTES: usize = 2 * 1024 * 1024;
33
34/// Admission allowances for payload or complete frame bytes.
35#[must_use]
36pub const fn limits(bytes: usize) -> Limits {
37    Limits {
38        bytes,
39        allocation: MAX_HEAP_BYTES.saturating_add(bytes),
40        nodes: MAX_NODES,
41        depth: MAX_DEPTH,
42    }
43}
44
45/// Allocation-free sizing policy retaining the same traversal heap allowance.
46///
47/// A size may exceed delivery limits so precommit callers can return the typed
48/// oversized-reply error. No output buffer is allocated under this allowance.
49#[must_use]
50pub const fn sizing_limits() -> Limits {
51    limits(usize::MAX - MAX_HEAP_BYTES)
52}
53
54/// Encode a native payload through IC Wire's bounded codec.
55pub fn encode_one<T: Serialize>(value: T) -> Result<Vec<u8>, Error> {
56    ic_wire::native::encode(&value, limits(MAX_REPLY_BYTES))
57}
58
59/// Measure a reply payload under the same resource limits as [`encode_one`].
60///
61/// This allocates no output buffer. Unlike [`encoded_len`], it refuses payloads
62/// above the reply byte ceiling. Pass the same owned or borrowed value shape
63/// as encoding so IC Wire applies identical traversal admission.
64pub fn encoded_reply_len<T: Serialize>(value: T) -> Result<usize, Error> {
65    ic_wire::native::encoded_len(&value, limits(MAX_REPLY_BYTES))
66}
67
68/// Decode one complete payload through IC Wire's bounded codec.
69///
70/// Maps, sets and custom visitors may normalize input; successful decoding does
71/// not establish canonical ordering or uniqueness. Retain the original bytes
72/// for exact retries, signatures or hashes instead of re-encoding the value.
73pub fn decode_one<T: DeserializeOwned>(bytes: &[u8]) -> Result<T, Error> {
74    ic_wire::native::decode(bytes, limits(MAX_REPLY_BYTES))
75}
76
77/// Measure native payload bytes without allocating output storage.
78pub fn encoded_len<T: Serialize + ?Sized>(value: &T) -> Result<usize, Error> {
79    ic_wire::native::encoded_len(value, sizing_limits())
80}
81
82#[cfg(test)]
83mod tests;