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;