soroban_env_common/
bytes.rs

1use crate::{
2    declare_tag_based_object_wrapper,
3    xdr::{ScErrorCode, ScErrorType},
4    Env, Error, TryFromVal, TryIntoVal, Val,
5};
6
7declare_tag_based_object_wrapper!(BytesObject);
8
9impl<E: Env, const N: usize> TryFromVal<E, BytesObject> for [u8; N] {
10    type Error = Error;
11
12    fn try_from_val(env: &E, val: &BytesObject) -> Result<Self, Self::Error> {
13        let len: u32 = env.bytes_len(*val).map_err(Into::into)?.into();
14        let len = len as usize;
15        if len != N {
16            return Err(Error::from_type_and_code(
17                ScErrorType::Value,
18                ScErrorCode::UnexpectedSize,
19            ));
20        }
21        let mut arr = [0u8; N];
22        env.bytes_copy_to_slice(*val, Val::U32_ZERO, &mut arr)
23            .map_err(Into::into)?;
24        Ok(arr)
25    }
26}
27
28impl<E: Env, const N: usize> TryFromVal<E, Val> for [u8; N] {
29    type Error = Error;
30
31    fn try_from_val(env: &E, val: &Val) -> Result<Self, Self::Error> {
32        let bo: BytesObject = val.try_into()?;
33        bo.try_into_val(env)
34    }
35}
36
37#[cfg(feature = "std")]
38impl<E: Env> TryFromVal<E, BytesObject> for Vec<u8> {
39    type Error = Error;
40
41    fn try_from_val(env: &E, val: &BytesObject) -> Result<Self, Self::Error> {
42        let len: u32 = env.bytes_len(*val).map_err(Into::into)?.into();
43        let len = len as usize;
44        let mut vec = vec![0u8; len];
45        env.bytes_copy_to_slice(*val, Val::U32_ZERO, &mut vec)
46            .map_err(Into::into)?;
47        Ok(vec)
48    }
49}
50
51#[cfg(feature = "std")]
52impl<E: Env> TryFromVal<E, Val> for Vec<u8> {
53    type Error = Error;
54
55    fn try_from_val(env: &E, val: &Val) -> Result<Self, Self::Error> {
56        let bo: BytesObject = val.try_into()?;
57        bo.try_into_val(env)
58    }
59}
60
61impl<E: Env> TryFromVal<E, &[u8]> for BytesObject {
62    type Error = Error;
63    #[inline(always)]
64    fn try_from_val(env: &E, v: &&[u8]) -> Result<BytesObject, Self::Error> {
65        env.bytes_new_from_slice(v).map_err(Into::into)
66    }
67}
68
69impl<E: Env> TryFromVal<E, &[u8]> for Val {
70    type Error = Error;
71    #[inline(always)]
72    fn try_from_val(env: &E, v: &&[u8]) -> Result<Val, Self::Error> {
73        Ok(BytesObject::try_from_val(env, v)?.into())
74    }
75}
76
77impl<E: Env, const N: usize> TryFromVal<E, [u8; N]> for BytesObject {
78    type Error = Error;
79
80    fn try_from_val(env: &E, v: &[u8; N]) -> Result<Self, Self::Error> {
81        v.as_slice().try_into_val(env)
82    }
83}
84
85impl<E: Env, const N: usize> TryFromVal<E, [u8; N]> for Val {
86    type Error = Error;
87
88    fn try_from_val(env: &E, v: &[u8; N]) -> Result<Self, Self::Error> {
89        v.as_slice().try_into_val(env)
90    }
91}
92
93#[cfg(feature = "std")]
94impl<E: Env> TryFromVal<E, Vec<u8>> for BytesObject {
95    type Error = Error;
96
97    fn try_from_val(env: &E, v: &Vec<u8>) -> Result<Self, Self::Error> {
98        v.as_slice().try_into_val(env)
99    }
100}
101
102#[cfg(feature = "std")]
103impl<E: Env> TryFromVal<E, Vec<u8>> for Val {
104    type Error = Error;
105
106    fn try_from_val(env: &E, v: &Vec<u8>) -> Result<Self, Self::Error> {
107        v.as_slice().try_into_val(env)
108    }
109}