substrate_stellar_xdr/
compound_types.rs1use core::convert::AsRef;
4use sp_std::{prelude::*, vec::Vec};
5
6use crate::streams::{DecodeError, ReadStream, WriteStream};
7use crate::xdr_codec::XdrCodec;
8
9#[derive(Debug, Clone)]
11pub struct ExceedsMaximumLengthError {
12 pub requested_length: usize,
13 pub allowed_length: i32,
14}
15
16#[allow(dead_code)]
21#[derive(Debug, Clone, Eq, PartialEq)]
22pub struct LimitedVarOpaque<const N: i32>(Vec<u8>);
23
24impl<const N: i32> LimitedVarOpaque<N> {
25 pub fn new(vec: Vec<u8>) -> Result<Self, ExceedsMaximumLengthError> {
30 match vec.len() > N as usize {
31 true => Err(ExceedsMaximumLengthError {
32 requested_length: vec.len(),
33 allowed_length: N,
34 }),
35 false => Ok(LimitedVarOpaque(vec)),
36 }
37 }
38
39 pub fn get_vec(&self) -> &Vec<u8> {
41 &self.0
42 }
43}
44
45impl<const N: i32> XdrCodec for LimitedVarOpaque<N> {
46 fn to_xdr_buffered(&self, write_stream: &mut WriteStream) {
48 write_stream.write_next_u32(self.0.len() as u32);
49 write_stream.write_next_binary_data(&self.0[..]);
50 }
51
52 fn from_xdr_buffered<R: AsRef<[u8]>>(
54 read_stream: &mut ReadStream<R>,
55 ) -> Result<Self, DecodeError> {
56 let length = read_stream.read_next_u32()? as i32;
57 match length > N {
58 true => Err(DecodeError::VarOpaqueExceedsMaxLength {
59 at_position: read_stream.get_position(),
60 max_length: N,
61 actual_length: length,
62 }),
63 false => Ok(
64 LimitedVarOpaque::new(read_stream.read_next_binary_data(length as usize)?).unwrap(),
65 ),
66 }
67 }
68}
69
70#[allow(dead_code)]
75pub type UnlimitedVarOpaque = LimitedVarOpaque<{ i32::MAX }>;
76
77#[allow(dead_code)]
82#[derive(Debug, Clone, Eq, PartialEq)]
83pub struct LimitedString<const N: i32>(Vec<u8>);
84
85impl<const N: i32> LimitedString<N> {
86 pub fn new(vec: Vec<u8>) -> Result<Self, ExceedsMaximumLengthError> {
92 match vec.len() > N as usize {
93 true => Err(ExceedsMaximumLengthError {
94 requested_length: vec.len(),
95 allowed_length: N,
96 }),
97 false => Ok(LimitedString(vec)),
98 }
99 }
100
101 pub fn get_vec(&self) -> &Vec<u8> {
103 &self.0
104 }
105}
106
107impl<const N: i32> XdrCodec for LimitedString<N> {
108 fn to_xdr_buffered(&self, write_stream: &mut WriteStream) {
110 write_stream.write_next_u32(self.0.len() as u32);
111 write_stream.write_next_binary_data(&self.0[..]);
112 }
113
114 fn from_xdr_buffered<R: AsRef<[u8]>>(
116 read_stream: &mut ReadStream<R>,
117 ) -> Result<Self, DecodeError> {
118 let length = read_stream.read_next_u32()? as i32;
119 match length > N {
120 true => Err(DecodeError::StringExceedsMaxLength {
121 at_position: read_stream.get_position(),
122 max_length: N,
123 actual_length: length,
124 }),
125 false => Ok(
126 LimitedString::new(read_stream.read_next_binary_data(length as usize)?).unwrap(),
127 ),
128 }
129 }
130}
131
132#[allow(dead_code)]
137pub type UnlimitedString = LimitedString<{ i32::MAX }>;
138
139#[allow(dead_code)]
145#[derive(Debug, Clone, Eq, PartialEq)]
146pub struct LimitedVarArray<T, const N: i32>(Vec<T>);
147
148impl<T, const N: i32> LimitedVarArray<T, N> {
149 pub fn new(vec: Vec<T>) -> Result<Self, ExceedsMaximumLengthError> {
154 match vec.len() > N as usize {
155 true => Err(ExceedsMaximumLengthError {
156 requested_length: vec.len(),
157 allowed_length: N,
158 }),
159 false => Ok(LimitedVarArray(vec)),
160 }
161 }
162
163 pub fn get_vec(&self) -> &Vec<T> {
165 &self.0
166 }
167
168 pub fn push(&mut self, item: T) -> Result<(), ExceedsMaximumLengthError> {
172 if self.0.len() >= N as usize - 1 {
173 return Err(ExceedsMaximumLengthError {
174 requested_length: self.0.len() + 1,
175 allowed_length: N,
176 });
177 }
178
179 self.0.push(item);
180 Ok(())
181 }
182}
183
184impl<T: XdrCodec, const N: i32> XdrCodec for LimitedVarArray<T, N> {
185 fn to_xdr_buffered(&self, write_stream: &mut WriteStream) {
187 write_stream.write_next_u32(self.0.len() as u32);
188 for item in self.0.iter() {
189 item.to_xdr_buffered(write_stream);
190 }
191 }
192
193 fn from_xdr_buffered<R: AsRef<[u8]>>(
195 read_stream: &mut ReadStream<R>,
196 ) -> Result<Self, DecodeError> {
197 let length = read_stream.read_next_u32()? as i32;
198 match length > N {
199 true => Err(DecodeError::VarArrayExceedsMaxLength {
200 at_position: read_stream.get_position(),
201 max_length: N,
202 actual_length: length,
203 }),
204 false => {
205 let mut result = Vec::<T>::with_capacity(length as usize);
206 for _ in 0..length {
207 result.push(T::from_xdr_buffered(read_stream)?)
208 }
209 Ok(LimitedVarArray::new(result).unwrap())
210 }
211 }
212 }
213}
214
215#[allow(dead_code)]
220pub type UnlimitedVarArray<T> = LimitedVarArray<T, { i32::MAX }>;