Decode a tile payload previously written by `encode_sparse_tile`. The `payload` slice must start at the tag byte (i.e. after BlockFraming has been unwrapped by the segment reader).
(payload: &[u8])
| 51 | /// The `payload` slice must start at the tag byte (i.e. after BlockFraming |
| 52 | /// has been unwrapped by the segment reader). |
| 53 | pub fn decode_sparse_tile(payload: &[u8]) -> ArrayResult<SparseTile> { |
| 54 | if payload.len() < 2 { |
| 55 | return Err(ArrayError::SegmentCorruption { |
| 56 | detail: "sparse tile payload too short".into(), |
| 57 | }); |
| 58 | } |
| 59 | |
| 60 | let tag_result = peek_tag(payload).ok_or_else(|| { |
| 61 | // peek_tag returns None for both legacy msgpack and unknown bytes. |
| 62 | // The reader should never call us with a legacy payload. |
| 63 | ArrayError::SegmentCorruption { |
| 64 | detail: format!( |
| 65 | "decode_sparse_tile called with legacy or unknown tag byte: {:#04x}", |
| 66 | payload[0] |
| 67 | ), |
| 68 | } |
| 69 | })?; |
| 70 | |
| 71 | let version = payload[1]; |
| 72 | if version != SUPPORTED_PAYLOAD_VERSION { |
| 73 | return Err(ArrayError::SegmentCorruption { |
| 74 | detail: format!("unsupported tile payload version: {version}"), |
| 75 | }); |
| 76 | } |
| 77 | |
| 78 | match tag_result { |
| 79 | CodecTag::Raw => decode_raw(&payload[2..]), |
| 80 | CodecTag::Structural => decode_structural(&payload[2..]), |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | fn decode_raw(body: &[u8]) -> ArrayResult<SparseTile> { |
| 85 | zerompk::from_msgpack(body).map_err(|e| ArrayError::SegmentCorruption { |