Skip to main content

amaru_kernel/utils/
serde.rs

1// Copyright 2025 PRAGMA
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::collections::BTreeMap;
16
17use crate::{MemoizedTransactionOutput, TransactionInput};
18
19// ----------------------------------------------------------------------------------- Generic utils
20
21pub trait HasProxy: From<Self::Proxy> {
22    type Proxy;
23}
24
25pub fn deserialize_map_proxy<'de, K, V, D>(deserializer: D) -> Result<BTreeMap<K, V>, D::Error>
26where
27    D: serde::Deserializer<'de>,
28    K: Ord + HasProxy,
29    K::Proxy: serde::Deserialize<'de>,
30    V: HasProxy,
31    V::Proxy: serde::Deserialize<'de>,
32{
33    let entries: Vec<(K::Proxy, V::Proxy)> = serde::Deserialize::deserialize(deserializer)?;
34    Ok(entries.into_iter().map(|(k, v)| (K::from(k), V::from(v))).collect())
35}
36
37pub fn deserialize_option_proxy<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
38where
39    D: serde::Deserializer<'de>,
40    T: HasProxy,
41    T::Proxy: serde::Deserialize<'de>,
42{
43    let option: Option<T::Proxy> = serde::Deserialize::deserialize(deserializer)?;
44    Ok(option.map(T::from))
45}
46
47pub fn hex_to_bytes<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
48where
49    D: serde::Deserializer<'de>,
50{
51    let s: String = serde::Deserialize::deserialize(deserializer)?;
52    hex::decode(s).map_err(serde::de::Error::custom)
53}
54
55// -------------------------------------------------------------------------------- TransactionInput
56
57impl HasProxy for TransactionInput {
58    // NOTE: TranscationInput already defines a serde::Deserialize instance. The trait 'From' is
59    // also reflexive, so this works.
60    type Proxy = TransactionInput;
61}
62
63// ------------------------------------------------------------------------------- TransactionOutput
64
65impl HasProxy for MemoizedTransactionOutput {
66    type Proxy = MemoizedTransactionOutput;
67}