facet_format_msgpack/lib.rs
1//! MsgPack binary format for facet using the Tier-2 JIT architecture.
2//!
3//! This crate provides Tier-2 JIT deserialization for the MsgPack binary format.
4//! It implements `JitFormat` and `FormatJitParser` to enable direct byte-level
5//! parsing without going through the event abstraction.
6//!
7//! **Note:** This crate is Tier-2 only. It does not implement a full `FormatParser`
8//! (ParseEvent) stack. For non-JIT MsgPack support, use `facet-msgpack`.
9//!
10//! ## Supported Types (v1)
11//!
12//! - `Vec<bool>` - MsgPack booleans (0xC2/0xC3)
13//! - `Vec<u8>` - MsgPack bin (0xC4/0xC5/0xC6) - **bulk copy fast path**
14//! - `Vec<u32>`, `Vec<u64>`, `Vec<i32>`, `Vec<i64>` - MsgPack integers
15//!
16//! ## Wire Format
17//!
18//! This crate implements a subset of the MsgPack specification:
19//!
20//! | Type | Tags |
21//! |------|------|
22//! | Bool | `0xC2` (false), `0xC3` (true) |
23//! | Unsigned | fixint (`0x00-0x7F`), `0xCC` (u8), `0xCD` (u16), `0xCE` (u32), `0xCF` (u64) |
24//! | Signed | negative fixint (`0xE0-0xFF`), `0xD0` (i8), `0xD1` (i16), `0xD2` (i32), `0xD3` (i64) |
25//! | Binary | `0xC4` (bin8), `0xC5` (bin16), `0xC6` (bin32) |
26//! | Array | fixarray (`0x90-0x9F`), `0xDC` (array16), `0xDD` (array32) |
27
28#![cfg_attr(not(feature = "jit"), forbid(unsafe_code))]
29
30extern crate alloc;
31
32mod error;
33mod parser;
34
35#[cfg(feature = "jit")]
36pub mod jit;
37
38pub use error::MsgPackError;
39#[cfg(feature = "jit")]
40pub use jit::MsgPackJitFormat;
41pub use parser::MsgPackParser;
42
43// Re-export DeserializeError for convenience
44pub use facet_format::DeserializeError;
45
46/// Deserialize a value from MsgPack bytes.
47///
48/// This uses Tier-2 JIT for supported types. Types that aren't Tier-2 compatible
49/// will return an error with a detailed explanation of why (this crate is Tier-2 only).
50///
51/// # Supported Types (Tier-2 v1)
52///
53/// - `Vec<bool>`
54/// - `Vec<u8>` (as MsgPack bin)
55/// - `Vec<u32>`, `Vec<u64>`, `Vec<i32>`, `Vec<i64>`
56///
57/// # Example
58///
59/// ```
60/// use facet_format_msgpack::from_slice;
61///
62/// // MsgPack encoding: [fixarray(3), true, false, true]
63/// let bytes = &[0x93, 0xC3, 0xC2, 0xC3];
64/// let result: Vec<bool> = from_slice(bytes).unwrap();
65/// assert_eq!(result, vec![true, false, true]);
66/// ```
67#[cfg(feature = "jit")]
68pub fn from_slice<'de, T>(input: &'de [u8]) -> Result<T, DeserializeError<MsgPackError>>
69where
70 T: facet_core::Facet<'de>,
71{
72 use facet_format::jit::{Tier2DeserializeError, try_deserialize_format_with_reason};
73
74 let mut parser = MsgPackParser::new(input);
75
76 // Use Tier-2 format JIT with detailed error reporting
77 match try_deserialize_format_with_reason::<T, _>(&mut parser) {
78 Ok(value) => Ok(value),
79 Err(Tier2DeserializeError::ParserHasBufferedState) => Err(DeserializeError::Unsupported(
80 "facet-format-msgpack: parser has buffered state (internal error)".into(),
81 )),
82 Err(Tier2DeserializeError::Incompatible(reason)) => {
83 // Convert the detailed incompatibility reason to an error message
84 Err(DeserializeError::Unsupported(format!(
85 "facet-format-msgpack (Tier-2 only): {}",
86 reason
87 )))
88 }
89 Err(Tier2DeserializeError::Deserialize(e)) => Err(e),
90 }
91}
92
93/// Deserialize a value from MsgPack bytes (non-JIT fallback).
94///
95/// This function is only available when the `jit` feature is disabled.
96/// It will always fail because this crate is Tier-2 JIT only.
97#[cfg(not(feature = "jit"))]
98pub fn from_slice<'de, T>(_input: &'de [u8]) -> Result<T, DeserializeError<MsgPackError>>
99where
100 T: facet_core::Facet<'de>,
101{
102 Err(DeserializeError::Unsupported(
103 "facet-format-msgpack requires the 'jit' feature".into(),
104 ))
105}