neo_devpack/codec.rs
1// Copyright (c) 2025-2026 R3E Network
2// Licensed under the MIT License
3
4//! Serialization and deserialization utilities for Neo N3 smart contracts.
5//!
6//! This module provides compact binary serialization using postcard for storage
7//! and cross-contract communication.
8
9use neo_types::{NeoError, NeoResult};
10use serde::de::DeserializeOwned;
11use serde::Serialize;
12
13const MAX_CODEC_BYTES: usize = 1024 * 1024;
14
15/// Serializes a value to bytes using postcard.
16///
17/// # Type Parameters
18/// * `T` - The type to serialize, must implement `Serialize`
19///
20/// # Arguments
21/// * `value` - A reference to the value to serialize
22///
23/// # Returns
24/// * `Ok(Vec<u8>)` - The serialized bytes on success
25/// * `Err(NeoError)` - If serialization fails
26///
27/// # Examples
28///
29/// ```
30/// use neo_devpack::codec::serialize;
31///
32/// let value = 42i32;
33/// let bytes = serialize(&value).unwrap();
34/// ```
35pub fn serialize<T: Serialize>(value: &T) -> NeoResult<Vec<u8>> {
36 let bytes = postcard::to_allocvec(value)
37 .map_err(|err| NeoError::new(&format!("Failed to serialize value: {err}")))?;
38 if bytes.len() > MAX_CODEC_BYTES {
39 return Err(NeoError::new(
40 "Failed to serialize value: encoded payload exceeds 1048576 bytes",
41 ));
42 }
43 Ok(bytes)
44}
45
46/// Deserializes bytes to a value using postcard.
47///
48/// # Type Parameters
49/// * `T` - The type to deserialize, must implement `DeserializeOwned`
50///
51/// # Arguments
52/// * `bytes` - The bytes to deserialize from
53///
54/// # Returns
55/// * `Ok(T)` - The deserialized value on success
56/// * `Err(NeoError)` - If deserialization fails (e.g., invalid format)
57///
58/// # Examples
59///
60/// ```
61/// use neo_devpack::codec::{serialize, deserialize};
62///
63/// let value = 42i32;
64/// let bytes = serialize(&value).unwrap();
65/// let restored: i32 = deserialize(&bytes).unwrap();
66/// assert_eq!(value, restored);
67/// ```
68pub fn deserialize<T: DeserializeOwned>(bytes: &[u8]) -> NeoResult<T> {
69 if bytes.len() > MAX_CODEC_BYTES {
70 return Err(NeoError::new(
71 "Failed to deserialize bytes: encoded payload exceeds 1048576 bytes",
72 ));
73 }
74 postcard::from_bytes(bytes)
75 .map_err(|err| NeoError::new(&format!("Failed to deserialize bytes: {err}")))
76}