Skip to main content

soroban_sdk/
xdr.rs

1//! Convert values to and from [Bytes].
2//!
3//! All types that are convertible to and from [Val] implement the
4//! [ToXdr] and [FromXdr] traits, and serialize to the ScVal XDR form.
5//!
6//! ### Examples
7//!
8//! ```
9//! use soroban_sdk::{
10//!     xdr::{FromXdr, ToXdr},
11//!     Env, Bytes, IntoVal, TryFromVal,
12//! };
13//!
14//! let env = Env::default();
15//!
16//! let value: u32 = 5;
17//!
18//! let bytes = value.to_xdr(&env);
19//! assert_eq!(bytes.len(), 8);
20//!
21//! let roundtrip = u32::from_xdr(&env, &bytes);
22//! assert_eq!(roundtrip, Ok(value));
23//! ```
24
25use crate::{
26    env::internal::Env as _, unwrap::UnwrapInfallible, Bytes, Env, IntoVal, TryFromVal, Val,
27};
28
29// Re-export all the XDR from the environment.
30pub use crate::env::xdr::*;
31
32/// Implemented by types that can be serialized to [Bytes] as XDR.
33///
34/// All types that are convertible to [Val] implement this trait. The value is
35/// first converted to a [Val], then serialized to XDR in its [ScVal] form.
36///
37/// ### Examples
38///
39/// ```
40/// use soroban_sdk::{xdr::ToXdr, Env};
41///
42/// let env = Env::default();
43///
44/// let value: u32 = 5;
45/// let bytes = value.to_xdr(&env);
46/// assert_eq!(bytes.len(), 8);
47/// ```
48pub trait ToXdr {
49    /// Serializes the value to XDR as [Bytes].
50    fn to_xdr(self, env: &Env) -> Bytes;
51}
52
53/// Implemented by types that can be deserialized from [Bytes] containing XDR.
54///
55/// All types that are convertible from [Val] implement this trait. The bytes
56/// are deserialized from their [ScVal] XDR form into a [Val], then converted
57/// to the target type.
58///
59/// ### Errors
60///
61/// Returns an error if the [Val] cannot be converted into the target type.
62///
63/// ### Panics
64///
65/// Panics if the provided bytes are not valid XDR for an [ScVal].
66///
67/// ### Examples
68///
69/// ```
70/// use soroban_sdk::{xdr::{ToXdr, FromXdr}, Env};
71///
72/// let env = Env::default();
73///
74/// let value: u32 = 5;
75/// let bytes = value.to_xdr(&env);
76///
77/// let roundtrip = u32::from_xdr(&env, &bytes);
78/// assert_eq!(roundtrip, Ok(5));
79/// ```
80pub trait FromXdr: Sized {
81    /// The error type returned if the [Val] cannot be converted into the
82    /// target type.
83    type Error;
84    /// Deserializes the value from XDR [Bytes].
85    ///
86    /// ### Errors
87    ///
88    /// Returns an error if the [Val] cannot be converted into the target
89    /// type.
90    ///
91    /// ### Panics
92    ///
93    /// Panics if the provided bytes are not valid XDR for an [ScVal].
94    fn from_xdr(env: &Env, b: &Bytes) -> Result<Self, Self::Error>;
95}
96
97impl<T> ToXdr for T
98where
99    T: IntoVal<Env, Val>,
100{
101    fn to_xdr(self, env: &Env) -> Bytes {
102        let val: Val = self.into_val(env);
103        let bin = env.serialize_to_bytes(val).unwrap_infallible();
104        unsafe { Bytes::unchecked_new(env.clone(), bin) }
105    }
106}
107
108impl<T> FromXdr for T
109where
110    T: TryFromVal<Env, Val>,
111{
112    type Error = T::Error;
113
114    fn from_xdr(env: &Env, b: &Bytes) -> Result<Self, Self::Error> {
115        let t = env.deserialize_from_bytes(b.into()).unwrap_infallible();
116        T::try_from_val(env, &t)
117    }
118}