Maps (tag, bytes) to EncodeRequest using the sealed `nan_box` layout.
(tag: u32, bytes: &[u8])
| 172 | |
| 173 | // Maps (tag, bytes) to EncodeRequest using the sealed `nan_box` layout. |
| 174 | pub fn classify_encode(tag: u32, bytes: &[u8]) -> EncodeRequest<'_> { |
| 175 | use nan_box::*; |
| 176 | |
| 177 | match Tag::from_u32(tag) { |
| 178 | Some(Tag::None) => EncodeRequest::Direct(TAG_NONE), |
| 179 | Some(Tag::Bool) => { |
| 180 | let b = !bytes.is_empty() && bytes[0] != 0; |
| 181 | EncodeRequest::Direct(if b { TAG_TRUE } else { TAG_FALSE }) |
| 182 | } |
| 183 | Some(Tag::Int) => { |
| 184 | // Wire format is 16 bytes (i128) covering Edge Python's full int range. |
| 185 | if bytes.len() != 16 { return EncodeRequest::Invalid; } |
| 186 | let mut buf = [0u8; 16]; |
| 187 | buf.copy_from_slice(bytes); |
| 188 | let i = i128::from_le_bytes(buf); |
| 189 | // Fits in 47-bit inline range -> emit as Val::int directly; else heap-alloc LongInt. |
| 190 | if (INLINE_INT_MIN..=INLINE_INT_MAX).contains(&i) { |
| 191 | EncodeRequest::Direct(TAG_INT | ((i as i64) as u64 & INT_PAYLOAD_MASK)) |
| 192 | } else { |
| 193 | EncodeRequest::AllocLongInt(i) |
| 194 | } |
| 195 | } |
| 196 | Some(Tag::Float) => { |
| 197 | if bytes.len() != 8 { return EncodeRequest::Invalid; } |
| 198 | let mut buf = [0u8; 8]; |
| 199 | buf.copy_from_slice(bytes); |
| 200 | EncodeRequest::Direct(f64::from_le_bytes(buf).to_bits()) |
| 201 | } |
| 202 | Some(Tag::Bytes) => match core::str::from_utf8(bytes) { |
| 203 | Ok(s) => EncodeRequest::AllocStr(s), |
| 204 | Err(_) => EncodeRequest::Invalid, |
| 205 | }, |
| 206 | // Raw bytes bypass UTF-8 validation and become a Python `bytes`. |
| 207 | Some(Tag::Raw) => EncodeRequest::AllocBytes(bytes), |
| 208 | None => EncodeRequest::Invalid, |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | // edge_decode outcome: Primitive (ready bytes), Heap (host materializes), or Invalid. |
| 213 | pub enum DecodeBits { |
no test coverage detected