1#[allow(unused_imports, clippy::wildcard_imports)]
2use super::*;
3
4#[cfg_attr(feature = "serde", cfg_eval::cfg_eval)]
74#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
75#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
76#[cfg_attr(
77 all(feature = "serde", feature = "alloc"),
78 serde_with::serde_as,
79 derive(serde::Serialize, serde::Deserialize),
80 serde(rename_all = "snake_case")
81)]
82#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
83#[allow(clippy::large_enum_variant)]
84pub enum ScVal {
85 Bool(bool),
86 Void,
87 Error(ScError),
88 U32(u32),
89 I32(i32),
90 U64(
91 #[cfg_attr(
92 all(feature = "serde", feature = "alloc"),
93 serde_as(as = "NumberOrString")
94 )]
95 u64,
96 ),
97 I64(
98 #[cfg_attr(
99 all(feature = "serde", feature = "alloc"),
100 serde_as(as = "NumberOrString")
101 )]
102 i64,
103 ),
104 Timepoint(TimePoint),
105 Duration(Duration),
106 U128(UInt128Parts),
107 I128(Int128Parts),
108 U256(UInt256Parts),
109 I256(Int256Parts),
110 Bytes(ScBytes),
111 String(ScString),
112 Symbol(ScSymbol),
113 Vec(Option<ScVec>),
114 Map(Option<ScMap>),
115 Address(ScAddress),
116 ContractInstance(ScContractInstance),
117 LedgerKeyContractInstance,
118 LedgerKeyNonce(ScNonceKey),
119 ExecutableTag(ScString),
120}
121
122#[cfg(feature = "alloc")]
123impl Default for ScVal {
124 fn default() -> Self {
125 Self::Bool(bool::default())
126 }
127}
128
129impl ScVal {
130 const _VARIANTS: &[ScValType] = &[
131 ScValType::Bool,
132 ScValType::Void,
133 ScValType::Error,
134 ScValType::U32,
135 ScValType::I32,
136 ScValType::U64,
137 ScValType::I64,
138 ScValType::Timepoint,
139 ScValType::Duration,
140 ScValType::U128,
141 ScValType::I128,
142 ScValType::U256,
143 ScValType::I256,
144 ScValType::Bytes,
145 ScValType::String,
146 ScValType::Symbol,
147 ScValType::Vec,
148 ScValType::Map,
149 ScValType::Address,
150 ScValType::ContractInstance,
151 ScValType::LedgerKeyContractInstance,
152 ScValType::LedgerKeyNonce,
153 ScValType::ExecutableTag,
154 ];
155 pub const VARIANTS: [ScValType; Self::_VARIANTS.len()] = {
156 let mut arr = [Self::_VARIANTS[0]; Self::_VARIANTS.len()];
157 let mut i = 1;
158 while i < Self::_VARIANTS.len() {
159 arr[i] = Self::_VARIANTS[i];
160 i += 1;
161 }
162 arr
163 };
164 const _VARIANTS_STR: &[&str] = &[
165 "Bool",
166 "Void",
167 "Error",
168 "U32",
169 "I32",
170 "U64",
171 "I64",
172 "Timepoint",
173 "Duration",
174 "U128",
175 "I128",
176 "U256",
177 "I256",
178 "Bytes",
179 "String",
180 "Symbol",
181 "Vec",
182 "Map",
183 "Address",
184 "ContractInstance",
185 "LedgerKeyContractInstance",
186 "LedgerKeyNonce",
187 "ExecutableTag",
188 ];
189 pub const VARIANTS_STR: [&'static str; Self::_VARIANTS_STR.len()] = {
190 let mut arr = [Self::_VARIANTS_STR[0]; Self::_VARIANTS_STR.len()];
191 let mut i = 1;
192 while i < Self::_VARIANTS_STR.len() {
193 arr[i] = Self::_VARIANTS_STR[i];
194 i += 1;
195 }
196 arr
197 };
198
199 #[must_use]
200 pub const fn name(&self) -> &'static str {
201 match self {
202 Self::Bool(_) => "Bool",
203 Self::Void => "Void",
204 Self::Error(_) => "Error",
205 Self::U32(_) => "U32",
206 Self::I32(_) => "I32",
207 Self::U64(_) => "U64",
208 Self::I64(_) => "I64",
209 Self::Timepoint(_) => "Timepoint",
210 Self::Duration(_) => "Duration",
211 Self::U128(_) => "U128",
212 Self::I128(_) => "I128",
213 Self::U256(_) => "U256",
214 Self::I256(_) => "I256",
215 Self::Bytes(_) => "Bytes",
216 Self::String(_) => "String",
217 Self::Symbol(_) => "Symbol",
218 Self::Vec(_) => "Vec",
219 Self::Map(_) => "Map",
220 Self::Address(_) => "Address",
221 Self::ContractInstance(_) => "ContractInstance",
222 Self::LedgerKeyContractInstance => "LedgerKeyContractInstance",
223 Self::LedgerKeyNonce(_) => "LedgerKeyNonce",
224 Self::ExecutableTag(_) => "ExecutableTag",
225 }
226 }
227
228 #[must_use]
229 pub const fn discriminant(&self) -> ScValType {
230 #[allow(clippy::match_same_arms)]
231 match self {
232 Self::Bool(_) => ScValType::Bool,
233 Self::Void => ScValType::Void,
234 Self::Error(_) => ScValType::Error,
235 Self::U32(_) => ScValType::U32,
236 Self::I32(_) => ScValType::I32,
237 Self::U64(_) => ScValType::U64,
238 Self::I64(_) => ScValType::I64,
239 Self::Timepoint(_) => ScValType::Timepoint,
240 Self::Duration(_) => ScValType::Duration,
241 Self::U128(_) => ScValType::U128,
242 Self::I128(_) => ScValType::I128,
243 Self::U256(_) => ScValType::U256,
244 Self::I256(_) => ScValType::I256,
245 Self::Bytes(_) => ScValType::Bytes,
246 Self::String(_) => ScValType::String,
247 Self::Symbol(_) => ScValType::Symbol,
248 Self::Vec(_) => ScValType::Vec,
249 Self::Map(_) => ScValType::Map,
250 Self::Address(_) => ScValType::Address,
251 Self::ContractInstance(_) => ScValType::ContractInstance,
252 Self::LedgerKeyContractInstance => ScValType::LedgerKeyContractInstance,
253 Self::LedgerKeyNonce(_) => ScValType::LedgerKeyNonce,
254 Self::ExecutableTag(_) => ScValType::ExecutableTag,
255 }
256 }
257
258 #[must_use]
259 pub const fn variants() -> [ScValType; Self::_VARIANTS.len()] {
260 Self::VARIANTS
261 }
262}
263
264impl Name for ScVal {
265 #[must_use]
266 fn name(&self) -> &'static str {
267 Self::name(self)
268 }
269}
270
271impl Discriminant<ScValType> for ScVal {
272 #[must_use]
273 fn discriminant(&self) -> ScValType {
274 Self::discriminant(self)
275 }
276}
277
278impl Variants<ScValType> for ScVal {
279 fn variants() -> slice::Iter<'static, ScValType> {
280 Self::VARIANTS.iter()
281 }
282}
283
284impl Union<ScValType> for ScVal {}
285
286impl ReadXdr for ScVal {
287 #[cfg(feature = "std")]
288 fn read_xdr<R: Read>(r: &mut Limited<R>) -> Result<Self, Error> {
289 r.with_limited_depth(|r| {
290 let dv: ScValType = <ScValType as ReadXdr>::read_xdr(r)?;
291 #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)]
292 let v = match dv {
293 ScValType::Bool => Self::Bool(bool::read_xdr(r)?),
294 ScValType::Void => Self::Void,
295 ScValType::Error => Self::Error(ScError::read_xdr(r)?),
296 ScValType::U32 => Self::U32(u32::read_xdr(r)?),
297 ScValType::I32 => Self::I32(i32::read_xdr(r)?),
298 ScValType::U64 => Self::U64(u64::read_xdr(r)?),
299 ScValType::I64 => Self::I64(i64::read_xdr(r)?),
300 ScValType::Timepoint => Self::Timepoint(TimePoint::read_xdr(r)?),
301 ScValType::Duration => Self::Duration(Duration::read_xdr(r)?),
302 ScValType::U128 => Self::U128(UInt128Parts::read_xdr(r)?),
303 ScValType::I128 => Self::I128(Int128Parts::read_xdr(r)?),
304 ScValType::U256 => Self::U256(UInt256Parts::read_xdr(r)?),
305 ScValType::I256 => Self::I256(Int256Parts::read_xdr(r)?),
306 ScValType::Bytes => Self::Bytes(ScBytes::read_xdr(r)?),
307 ScValType::String => Self::String(ScString::read_xdr(r)?),
308 ScValType::Symbol => Self::Symbol(ScSymbol::read_xdr(r)?),
309 ScValType::Vec => Self::Vec(Option::<ScVec>::read_xdr(r)?),
310 ScValType::Map => Self::Map(Option::<ScMap>::read_xdr(r)?),
311 ScValType::Address => Self::Address(ScAddress::read_xdr(r)?),
312 ScValType::ContractInstance => {
313 Self::ContractInstance(ScContractInstance::read_xdr(r)?)
314 }
315 ScValType::LedgerKeyContractInstance => Self::LedgerKeyContractInstance,
316 ScValType::LedgerKeyNonce => Self::LedgerKeyNonce(ScNonceKey::read_xdr(r)?),
317 ScValType::ExecutableTag => Self::ExecutableTag(ScString::read_xdr(r)?),
318 #[allow(unreachable_patterns)]
319 _ => return Err(Error::Invalid),
320 };
321 Ok(v)
322 })
323 }
324}
325
326impl WriteXdr for ScVal {
327 #[cfg(feature = "std")]
328 fn write_xdr<W: Write>(&self, w: &mut Limited<W>) -> Result<(), Error> {
329 w.with_limited_depth(|w| {
330 self.discriminant().write_xdr(w)?;
331 #[allow(clippy::match_same_arms)]
332 match self {
333 Self::Bool(v) => v.write_xdr(w)?,
334 Self::Void => ().write_xdr(w)?,
335 Self::Error(v) => v.write_xdr(w)?,
336 Self::U32(v) => v.write_xdr(w)?,
337 Self::I32(v) => v.write_xdr(w)?,
338 Self::U64(v) => v.write_xdr(w)?,
339 Self::I64(v) => v.write_xdr(w)?,
340 Self::Timepoint(v) => v.write_xdr(w)?,
341 Self::Duration(v) => v.write_xdr(w)?,
342 Self::U128(v) => v.write_xdr(w)?,
343 Self::I128(v) => v.write_xdr(w)?,
344 Self::U256(v) => v.write_xdr(w)?,
345 Self::I256(v) => v.write_xdr(w)?,
346 Self::Bytes(v) => v.write_xdr(w)?,
347 Self::String(v) => v.write_xdr(w)?,
348 Self::Symbol(v) => v.write_xdr(w)?,
349 Self::Vec(v) => v.write_xdr(w)?,
350 Self::Map(v) => v.write_xdr(w)?,
351 Self::Address(v) => v.write_xdr(w)?,
352 Self::ContractInstance(v) => v.write_xdr(w)?,
353 Self::LedgerKeyContractInstance => ().write_xdr(w)?,
354 Self::LedgerKeyNonce(v) => v.write_xdr(w)?,
355 Self::ExecutableTag(v) => v.write_xdr(w)?,
356 };
357 Ok(())
358 })
359 }
360}