ic_wire/lib.rs
1//! Bounded Postcard contracts for controlled IC endpoints.
2//!
3//! Transport, authentication, semantic validation and replay policy belong to
4//! consumers. See the runtime guide for maintained wire rules.
5#![no_std]
6#![doc = include_str!("../README.md")]
7extern crate alloc;
8mod bounded;
9mod contract;
10mod float;
11mod packed;
12#[cfg(all(feature = "platform-types", not(target_family = "wasm")))]
13mod platform_types;
14pub mod serde_packed;
15pub use packed::{Packed, PackedElement};
16/// Bounded Serde/Postcard encoding, decoding and request/response framing.
17pub mod native;
18/// Optional TypeScript generation on native hosts.
19/// Forwarding the feature on Wasm retains only the runtime codec.
20#[cfg(all(feature = "typescript", not(target_family = "wasm")))]
21pub mod typescript;
22pub use bounded::{Bytes, BytesRef, List, PackedI16, Text, TextRef};
23pub use float::{FiniteF32, FiniteF64};
24#[cfg(feature = "typescript")]
25pub use ic_wire_derive::Wire;
26
27/// Owned binary data using Serde's bulk byte-buffer representation.
28///
29/// This is the same type as `serde_bytes::ByteBuf`, available without a separate
30/// consumer dependency. Use [`Bytes<N>`] when the field needs a byte limit.
31/// Native [`Limits`] still apply; TypeScript metadata projects to `Uint8Array`.
32/// Compared with `Vec<u8>`, bytes are identical but admission is bulk rather
33/// than per-element. Existing ByteBuf bytes, limits and primitive checks are
34/// unchanged by this re-export; no migration is needed from serde_bytes::ByteBuf.
35pub use serde_bytes::ByteBuf;
36
37/// Fixed-width binary data using Serde's bulk byte representation.
38///
39/// This re-exports `serde_bytes::ByteArray<N>`; no consumer dependency is needed.
40/// TypeScript projects it to `Uint8Array` with length exactly `N`.
41/// Unlike `[u8; N]`, its Postcard bytes include a length prefix: `[0, 255]`
42/// is `00 ff` as an array and `02 00 ff` as `ByteArray<2>`. Adopting this type
43/// changes the contract and bulk admission; coordinate consumers, regenerate
44/// clients and qualify limits. Existing array layouts remain unchanged.
45pub use serde_bytes::ByteArray;
46
47/// Implementation dependencies used by generated contracts.
48#[doc(hidden)]
49pub mod __private {
50 pub use alloc::{collections::BinaryHeap, vec::Vec};
51 pub use serde;
52 #[cfg(all(feature = "typescript", not(target_family = "wasm")))]
53 pub use serde_json;
54}
55
56/// Typed codec/admission failure, distinct from transport and application errors.
57#[derive(Clone, Copy, Debug, Eq, PartialEq)]
58pub enum Error {
59 /// Wire, collection, text or caller-output allowance exceeded.
60 Limit,
61 /// Allocation failed within an admitted allowance.
62 Allocation,
63 /// Invalid or truncated Postcard representation.
64 Malformed,
65 /// Bytes remain after the expected value.
66 Trailing,
67 /// Envelope marker, method identity or direction differs.
68 Identity,
69}
70impl core::fmt::Display for Error {
71 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
72 // Display must survive builds that strip derived Debug implementations.
73 // Text changes from e.g. "wire Malformed" to "wire malformed"; enum
74 // meanings, protocol bytes and admission rules remain unchanged.
75 f.write_str(match self {
76 Self::Limit => "wire limit",
77 Self::Allocation => "wire allocation",
78 Self::Malformed => "wire malformed",
79 Self::Trailing => "wire trailing",
80 Self::Identity => "wire identity",
81 })
82 }
83}
84impl core::error::Error for Error {}
85
86/// Consumer-selected allowances for Serde traversal.
87#[derive(Clone, Copy, Debug)]
88pub struct Limits {
89 /// Maximum encoding bytes; framed APIs include the 11-byte header.
90 pub bytes: usize,
91 /// Conservative traversal allowance in bytes, not measured heap usage.
92 /// Reserves the entire [`Self::bytes`] allowance, then charges eight times
93 /// visited value sizes and text/byte lengths. Excludes caller input.
94 /// Encoding and decoding can require different allowances; see the crate guide.
95 pub allocation: usize,
96 /// Maximum visited value nodes, including unit elements.
97 pub nodes: usize,
98 /// Maximum nesting depth.
99 pub depth: usize,
100}