ultrasonic/
macros.rs

1// UltraSONIC: transactional execution layer with capability-based memory access for zk-AluVM
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Designed in 2019-2025 by Dr Maxim Orlovsky <orlovsky@ubideco.org>
6// Written in 2024-2025 by Dr Maxim Orlovsky <orlovsky@ubideco.org>
7//
8// Copyright (C) 2019-2024 LNP/BP Standards Association, Switzerland.
9// Copyright (C) 2024-2025 Laboratories for Ubiquitous Deterministic Computing (UBIDECO),
10//                         Institute for Distributed and Cognitive Systems (InDCS), Switzerland.
11// Copyright (C) 2019-2025 Dr Maxim Orlovsky.
12// All rights under the above copyrights are reserved.
13//
14// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
15// in compliance with the License. You may obtain a copy of the License at
16//
17//        http://www.apache.org/licenses/LICENSE-2.0
18//
19// Unless required by applicable law or agreed to in writing, software distributed under the License
20// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
21// or implied. See the License for the specific language governing permissions and limitations under
22// the License.
23
24// TODO: Move to amplify
25/// Implement serde serialize and deserialize traits for a type wrapping another type, such that it
26/// uses Display and FromStr for human-readable serialization, and binary for non-human readable.
27#[macro_export]
28macro_rules! impl_serde_str_bin_wrapper {
29    ($ty:ty, $inner:ty) => {
30        impl serde::Serialize for $ty {
31            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
32            where S: serde::Serializer {
33                if serializer.is_human_readable() {
34                    serializer.serialize_str(&self.to_string())
35                } else {
36                    self.0.serialize(serializer)
37                }
38            }
39        }
40
41        impl<'de> serde::Deserialize<'de> for $ty {
42            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
43            where D: serde::Deserializer<'de> {
44                use serde::de::Error;
45                if deserializer.is_human_readable() {
46                    let s = String::deserialize(deserializer)?;
47                    s.parse().map_err(D::Error::custom)
48                } else {
49                    <$inner>::deserialize(deserializer).map(Self)
50                }
51            }
52        }
53    };
54}
55
56/// Testing macro for implementations of [`impl_serde_str_bin_wrapper`].
57#[macro_export]
58macro_rules! test_serde_str_bin_wrapper {
59    ($val:expr, $str:literal, $dat:expr) => {
60        use serde_test::{assert_tokens, Configure, Token};
61        assert_eq!(bincode::serialize(&$val).unwrap(), $dat);
62        assert_eq!(bincode::serialize(&$val).unwrap(), bincode::serialize(&$val.0).unwrap());
63        assert_tokens(&$val.readable(), &[Token::Str($str)]);
64    };
65}