Skip to main content

wry_bindgen/encode/
mod.rs

1//! Core encoding and decoding traits for the binary protocol.
2//!
3//! This module provides traits for serializing and deserializing Rust types
4//! to/from the binary IPC protocol.
5
6use alloc::vec::Vec;
7
8use crate::batch::Runtime;
9use crate::ipc::{DecodeError, DecodedData, EncodedData};
10
11/// Trait for encoding Rust values into the binary protocol.
12/// Each type specifies how to serialize itself.
13pub trait BinaryEncode<P = ()> {
14    fn encode(self, encoder: &mut EncodedData);
15}
16
17/// Trait for decoding values from the binary protocol.
18/// Each type specifies how to deserialize itself.
19pub trait BinaryDecode: Sized {
20    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError>;
21}
22
23/// Trait for converting a closure into a Closure wrapper.
24/// This trait is used instead of `From` to allow blanket implementations
25/// for all closure types without conflicting with other `From` impls.
26/// Output is a generic parameter (not associated type) to allow implementing
27/// the trait multiple times for the same type with different outputs.
28pub trait IntoClosure<M, Output> {
29    fn into_closure(self) -> Output;
30}
31
32/// Trait for return types that can be used in batched JS calls.
33/// Determines how the type behaves during batching.
34pub trait BatchableResult: BinaryDecode {
35    /// Returns Some(placeholder) for opaque types that can be batched,
36    /// None for types that require flushing to get the actual value.
37    ///
38    /// For opaque types (JsValue, Closure), this reserves a heap ID and returns a placeholder.
39    /// For trivial types like (), this returns the known value.
40    /// For value types (primitives, String, Vec, etc.), returns None to trigger a flush.
41    ///
42    /// Default implementation returns None (requires flush).
43    fn try_placeholder(_: &mut Runtime) -> Option<Self> {
44        None
45    }
46}
47
48/// Marker for cached type definition (type already sent, reference by ID).
49/// Format: [TYPE_CACHED] [type_id: u32]
50pub(crate) const TYPE_CACHED: u8 = 0xFF;
51
52/// Marker for full type definition (first time sending this type signature).
53/// Format: [TYPE_FULL] [type_id: u32] [param_count: u8] [param TypeDefs...] [return TypeDef]
54pub(crate) const TYPE_FULL: u8 = 0xFE;
55
56/// Type tags for the binary type definition protocol.
57/// Used to encode type information that JavaScript can parse to create TypeClass instances.
58#[repr(u8)]
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub enum TypeTag {
61    // Primitive types
62    Null = 0,
63    Bool = 1,
64    U8 = 2,
65    U16 = 3,
66    U32 = 4,
67    U64 = 5,
68    U128 = 6,
69    I8 = 7,
70    I16 = 8,
71    I32 = 9,
72    I64 = 10,
73    I128 = 11,
74    F32 = 12,
75    F64 = 13,
76    Usize = 14,
77    Isize = 15,
78    String = 16,
79    HeapRef = 17,
80    // Compound types
81    /// Callback type: followed by param_count (u8), param TypeDefs..., return TypeDef
82    Callback = 18,
83    /// Option type: followed by inner TypeDef. Encodes as u8 flag (0=None, 1=Some) + value if Some
84    Option = 19,
85    /// Result type: followed by ok TypeDef and err TypeDef. Encodes as u8 flag (0=Err, 1=Ok) + value
86    Result = 20,
87    /// Array type: followed by element TypeDef. Encodes as u32 length + elements
88    Array = 21,
89    /// Borrowed reference: uses the borrow stack (indices 1-127) instead of the heap.
90    /// Automatically cleaned up after each operation completes.
91    BorrowedRef = 22,
92    /// Clamped u8 array type: represents Uint8ClampedArray in JS.
93    /// Element type is always u8. Encodes as u32 length + u8 elements.
94    U8Clamped = 23,
95    /// String enum type: encodes as u32 index, but type def includes variant strings.
96    /// Format: [StringEnum tag] [variant_count: u8] [for each: string_len: u32, string_bytes...]
97    /// Values encode as u32 discriminant. JS decodes using the lookup array.
98    StringEnum = 24,
99}
100
101/// Trait for types that can encode their type definition into the binary protocol.
102/// This is used to send type information to JavaScript for callback arguments.
103pub trait EncodeTypeDef {
104    /// Encode this type's definition into the buffer.
105    /// For primitives, this is just the TypeTag byte.
106    /// For callbacks, this includes param count, param types, and return type.
107    fn encode_type_def(buf: &mut Vec<u8>);
108}
109
110mod callbacks;
111mod clamped;
112mod containers;
113mod primitives;
114#[cfg(test)]
115mod tests;
116mod values;
117
118pub use callbacks::CallbackKey;
119pub(crate) use callbacks::CallbackPolicy;