1#[cfg(feature = "owned-model")]
7use crate::{
8 ContractEnumDef, ContractEnumVariant, ContractEventDef,
9 ContractExceptionType, ContractField, ContractSignedTokenPreimage,
10 ContractSpec, ContractSpecId, ContractSpecInterface, ContractSpecMethod,
11 ContractSpecString, ContractStructDef, ContractType, ContractTypeDef,
12 ContractUnionCase, ContractUnionCaseType, ContractUnionDef, SpecFragment,
13 SpecInterfaceAnchor, SpecInterfaceFragment, SpecMethodFragment,
14};
15#[cfg(feature = "owned-model")]
16use alloc::{boxed::Box, vec::Vec};
17
18use xdrs::*;
19
20#[cfg(feature = "owned-model")]
21fn to_spec_string(s: &str) -> ContractSpecString {
22 ContractSpecString::try_from(s).expect("spec string conversion")
23}
24
25#[derive(
35 Debug,
36 Clone,
37 Copy,
38 PartialEq,
39 Eq,
40 PartialOrd,
41 Ord,
42 Hash,
43 ConstWriteXDR,
44 WriteXDR,
45)]
46pub struct ContractSpecIdView<'a> {
47 pub crate_name: &'a str,
49 pub major: &'a str,
52 pub module_path: &'a str,
56 pub declared: &'a str,
59}
60
61#[cfg(feature = "owned-model")]
62impl From<ContractSpecIdView<'_>> for ContractSpecId {
63 fn from(value: ContractSpecIdView<'_>) -> Self {
64 Self {
65 crate_name: to_spec_string(value.crate_name),
66 major: to_spec_string(value.major),
67 module_path: to_spec_string(value.module_path),
68 declared: to_spec_string(value.declared),
69 }
70 }
71}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
74pub struct ContractSpecView<'a> {
75 pub interfaces: &'a [ContractSpecInterfaceView<'a>],
76 pub type_defs: &'a [ContractTypeDefView<'a>],
77 pub events: &'a [ContractEventDefView<'a>],
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
81pub struct ContractSpecInterfaceView<'a> {
82 pub name: &'a str,
83 pub version: &'a str,
84 pub throws: &'a [ContractExceptionTypeView<'a>],
85 pub methods: &'a [ContractSpecMethodView<'a>],
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
89pub struct ContractSpecMethodView<'a> {
90 pub name: &'a str,
91 pub args: &'a [ContractFieldView<'a>],
92 pub return_type: ContractTypeView<'a>,
93 pub effect: Option<ContractMethodEffectView>,
94}
95
96#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
99#[repr(i32)]
100pub enum ContractMethodEffectView {
101 Pure = 1,
103 ReadOnly = 2,
105 StateChanging = 3,
107}
108
109#[cfg(feature = "owned-model")]
110impl From<ContractMethodEffectView> for crate::ContractMethodEffect {
111 fn from(value: ContractMethodEffectView) -> Self {
112 Self(value as i32)
113 }
114}
115
116#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
117pub struct ContractFieldView<'a> {
118 pub name: &'a str,
119 pub ty: ContractTypeView<'a>,
120}
121
122#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
123#[repr(i32)]
124pub enum ContractTypeView<'a> {
125 Void = 0,
126 Bool = 1,
127 U32 = 2,
128 I32 = 3,
129 U64 = 4,
130 I64 = 5,
131 U128 = 6,
132 I128 = 7,
133 String = 8,
134 Bytes = 9,
135 Address = 10,
136 Option(&'a ContractTypeView<'a>) = 11,
137 Vector(ContractVectorTypeView<'a>) = 12,
138 Tuple(&'a [ContractTypeView<'a>]) = 13,
139 Named(ContractSpecIdView<'a>) = 14,
140 U8 = 15,
141 Array(ContractArrayTypeView<'a>) = 16,
142 SignedToken(Option<&'a ContractTypeView<'a>>) = 17,
148 U256 = 18,
149 I256 = 19,
150}
151
152#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
153pub struct ContractExceptionTypeView<'a> {
154 pub selector: u64,
155 pub ty: ContractTypeView<'a>,
156}
157
158#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
159pub struct ContractArrayTypeView<'a> {
160 pub element: &'a ContractTypeView<'a>,
161 pub len: u32,
162}
163
164#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
165pub struct ContractVectorTypeView<'a> {
166 pub element: &'a ContractTypeView<'a>,
167 pub max_len: u32,
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
171#[repr(i32)]
172pub enum ContractTypeDefView<'a> {
173 Struct(ContractStructDefView<'a>) = 0,
174 Enum(ContractEnumDefView<'a>) = 1,
175 Union(ContractUnionDefView<'a>) = 2,
176}
177
178impl<'a> ContractTypeDefView<'a> {
179 pub const fn symbol(self) -> ContractSpecIdView<'a> {
180 match self {
181 Self::Struct(def) => def.name,
182 Self::Enum(def) => def.name,
183 Self::Union(def) => def.name,
184 }
185 }
186
187 pub const fn type_ref(self) -> ContractTypeView<'a> {
188 ContractTypeView::Named(self.symbol())
189 }
190}
191
192#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
193pub struct ContractStructDefView<'a> {
194 pub name: ContractSpecIdView<'a>,
195 pub fields: &'a [ContractFieldView<'a>],
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
199pub struct ContractEnumDefView<'a> {
200 pub name: ContractSpecIdView<'a>,
201 pub variants: &'a [ContractEnumVariantView<'a>],
202}
203
204#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
205pub struct ContractEnumVariantView<'a> {
206 pub name: &'a str,
207 pub value: i32,
208}
209
210#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
211pub struct ContractUnionDefView<'a> {
212 pub name: ContractSpecIdView<'a>,
213 pub cases: &'a [ContractUnionCaseView<'a>],
214}
215
216#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
217pub struct ContractUnionCaseView<'a> {
218 pub name: &'a str,
219 pub discriminant: i32,
220 pub case_type: ContractUnionCaseTypeView<'a>,
221}
222
223#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
224#[repr(i32)]
225pub enum ContractUnionCaseTypeView<'a> {
226 Void = 0,
227 Tuple(&'a [ContractTypeView<'a>]) = 1,
228 Struct(&'a [ContractFieldView<'a>]) = 2,
229}
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
235pub struct ContractEventDefView<'a> {
236 pub name: ContractSpecIdView<'a>,
237 pub signature: [u8; 32],
238 pub topics: &'a [ContractFieldView<'a>],
239 pub fields: &'a [ContractFieldView<'a>],
240}
241
242#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
243#[repr(i32)]
244pub enum SpecFragmentView<'a> {
245 Interface(SpecInterfaceFragmentView<'a>) = 0,
246 Method(SpecMethodFragmentView<'a>) = 1,
247 TypeDef(ContractTypeDefView<'a>) = 2,
248 ExportedTypeDef(ContractTypeDefView<'a>) = 3,
249 Event(ContractEventDefView<'a>) = 4,
250 ExportedEvent(ContractEventDefView<'a>) = 5,
251 InterfaceAnchor(SpecInterfaceAnchorView<'a>) = 6,
252}
253
254#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
255pub struct SpecInterfaceFragmentView<'a> {
256 pub interface_name: &'a str,
257 pub interface_version: &'a str,
258 pub declared_by: ContractSpecIdView<'a>,
259 pub throws: &'a [ContractExceptionTypeView<'a>],
260 pub emits: &'a [ContractSpecIdView<'a>],
265}
266
267#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
268pub struct SpecMethodFragmentView<'a> {
269 pub interface_name: &'a str,
270 pub interface_version: &'a str,
271 pub declared_by: ContractSpecIdView<'a>,
272 pub method: ContractSpecMethodView<'a>,
273}
274
275#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstWriteXDR, WriteXDR)]
279pub struct SpecInterfaceAnchorView<'a> {
280 pub interface_name: &'a str,
281 pub interface_version: &'a str,
282 pub declared_by: ContractSpecIdView<'a>,
283}
284
285#[cfg(feature = "owned-model")]
286impl From<ContractSpecView<'_>> for ContractSpec {
287 fn from(value: ContractSpecView<'_>) -> Self {
288 Self {
289 interfaces: value
290 .interfaces
291 .iter()
292 .copied()
293 .map(Into::into)
294 .collect::<Vec<_>>()
295 .try_into()
296 .unwrap(),
297 type_defs: value
298 .type_defs
299 .iter()
300 .copied()
301 .map(Into::into)
302 .collect::<Vec<_>>()
303 .try_into()
304 .unwrap(),
305 events: value
306 .events
307 .iter()
308 .copied()
309 .map(Into::into)
310 .collect::<Vec<_>>()
311 .try_into()
312 .unwrap(),
313 }
314 }
315}
316
317#[cfg(feature = "owned-model")]
318impl From<ContractEventDefView<'_>> for ContractEventDef {
319 fn from(value: ContractEventDefView<'_>) -> Self {
320 Self {
321 name: value.name.into(),
322 signature: value.signature.into(),
323 topics: value
324 .topics
325 .iter()
326 .copied()
327 .map(Into::into)
328 .collect::<Vec<_>>()
329 .try_into()
330 .unwrap(),
331 fields: value
332 .fields
333 .iter()
334 .copied()
335 .map(Into::into)
336 .collect::<Vec<_>>()
337 .try_into()
338 .unwrap(),
339 }
340 }
341}
342
343#[cfg(feature = "owned-model")]
344impl From<ContractExceptionTypeView<'_>> for ContractExceptionType {
345 fn from(value: ContractExceptionTypeView<'_>) -> Self {
346 Self {
347 selector: value.selector,
348 ty: value.ty.into(),
349 }
350 }
351}
352
353#[cfg(feature = "owned-model")]
354impl From<ContractSpecInterfaceView<'_>> for ContractSpecInterface {
355 fn from(value: ContractSpecInterfaceView<'_>) -> Self {
356 Self {
357 name: to_spec_string(value.name),
358 vers: to_spec_string(value.version),
359 throws: value
360 .throws
361 .iter()
362 .copied()
363 .map(Into::into)
364 .collect::<Vec<_>>()
365 .try_into()
366 .unwrap(),
367 methods: value
368 .methods
369 .iter()
370 .copied()
371 .map(Into::into)
372 .collect::<Vec<_>>()
373 .try_into()
374 .unwrap(),
375 }
376 }
377}
378
379#[cfg(feature = "owned-model")]
380impl From<ContractSpecMethodView<'_>> for ContractSpecMethod {
381 fn from(value: ContractSpecMethodView<'_>) -> Self {
382 Self {
383 name: to_spec_string(value.name),
384 args: value
385 .args
386 .iter()
387 .copied()
388 .map(Into::into)
389 .collect::<Vec<_>>()
390 .try_into()
391 .unwrap(),
392 return_type: value.return_type.into(),
393 effect: value.effect.map(Into::into),
394 }
395 }
396}
397
398#[cfg(feature = "owned-model")]
399impl From<ContractFieldView<'_>> for ContractField {
400 fn from(value: ContractFieldView<'_>) -> Self {
401 Self {
402 name: to_spec_string(value.name),
403 ty: value.ty.into(),
404 }
405 }
406}
407
408#[cfg(feature = "owned-model")]
409impl From<ContractTypeView<'_>> for ContractType {
410 fn from(value: ContractTypeView<'_>) -> Self {
411 match value {
412 ContractTypeView::Void => ContractType::Void,
413 ContractTypeView::Bool => ContractType::Bool,
414 ContractTypeView::U32 => ContractType::U32,
415 ContractTypeView::I32 => ContractType::I32,
416 ContractTypeView::U64 => ContractType::U64,
417 ContractTypeView::I64 => ContractType::I64,
418 ContractTypeView::U128 => ContractType::U128,
419 ContractTypeView::I128 => ContractType::I128,
420 ContractTypeView::String => ContractType::String,
421 ContractTypeView::Bytes => ContractType::Bytes,
422 ContractTypeView::Address => ContractType::Address,
423 ContractTypeView::Option(inner) => ContractType::Option {
424 option_inner: Box::new((*inner).into()),
425 },
426 ContractTypeView::Vector(inner) => ContractType::Vector {
427 vector: inner.into(),
428 },
429 ContractTypeView::Tuple(items) => ContractType::Tuple {
430 tuple: items
431 .iter()
432 .copied()
433 .map(Into::into)
434 .collect::<Vec<_>>()
435 .try_into()
436 .unwrap(),
437 },
438 ContractTypeView::Named(name) => {
439 ContractType::Named { named: name.into() }
440 }
441 ContractTypeView::U8 => ContractType::U8,
442 ContractTypeView::Array(array) => ContractType::Array {
443 array: array.into(),
444 },
445 ContractTypeView::SignedToken(inner) => {
446 ContractType::SignedToken {
447 signed_token_preimage: ContractSignedTokenPreimage {
448 preimage_type: inner
449 .map(|inner| Box::new((*inner).into())),
450 },
451 }
452 }
453 ContractTypeView::U256 => ContractType::U256,
454 ContractTypeView::I256 => ContractType::I256,
455 }
456 }
457}
458
459#[cfg(feature = "owned-model")]
460impl From<ContractArrayTypeView<'_>> for crate::ContractArrayType {
461 fn from(value: ContractArrayTypeView<'_>) -> Self {
462 Self {
463 element: Box::new((*value.element).into()),
464 len: value.len,
465 }
466 }
467}
468
469#[cfg(feature = "owned-model")]
470impl From<ContractVectorTypeView<'_>> for crate::ContractVectorType {
471 fn from(value: ContractVectorTypeView<'_>) -> Self {
472 Self {
473 element: Box::new((*value.element).into()),
474 max_len: value.max_len,
475 }
476 }
477}
478
479#[cfg(feature = "owned-model")]
480impl From<ContractTypeDefView<'_>> for ContractTypeDef {
481 fn from(value: ContractTypeDefView<'_>) -> Self {
482 match value {
483 ContractTypeDefView::Struct(def) => {
484 ContractTypeDef::TypeDefStruct {
485 struct_def: def.into(),
486 }
487 }
488 ContractTypeDefView::Enum(def) => ContractTypeDef::TypeDefEnum {
489 enum_def: def.into(),
490 },
491 ContractTypeDefView::Union(def) => ContractTypeDef::TypeDefUnion {
492 union_def: def.into(),
493 },
494 }
495 }
496}
497
498#[cfg(feature = "owned-model")]
499impl From<ContractStructDefView<'_>> for ContractStructDef {
500 fn from(value: ContractStructDefView<'_>) -> Self {
501 Self {
502 name: value.name.into(),
503 fields: value
504 .fields
505 .iter()
506 .copied()
507 .map(Into::into)
508 .collect::<Vec<_>>()
509 .try_into()
510 .unwrap(),
511 }
512 }
513}
514
515#[cfg(feature = "owned-model")]
516impl From<ContractEnumDefView<'_>> for ContractEnumDef {
517 fn from(value: ContractEnumDefView<'_>) -> Self {
518 Self {
519 name: value.name.into(),
520 variants: value
521 .variants
522 .iter()
523 .copied()
524 .map(Into::into)
525 .collect::<Vec<_>>()
526 .try_into()
527 .unwrap(),
528 }
529 }
530}
531
532#[cfg(feature = "owned-model")]
533impl From<ContractEnumVariantView<'_>> for ContractEnumVariant {
534 fn from(value: ContractEnumVariantView<'_>) -> Self {
535 Self {
536 name: to_spec_string(value.name),
537 value: value.value,
538 }
539 }
540}
541
542#[cfg(feature = "owned-model")]
543impl From<ContractUnionDefView<'_>> for ContractUnionDef {
544 fn from(value: ContractUnionDefView<'_>) -> Self {
545 Self {
546 name: value.name.into(),
547 cases: value
548 .cases
549 .iter()
550 .copied()
551 .map(Into::into)
552 .collect::<Vec<_>>()
553 .try_into()
554 .unwrap(),
555 }
556 }
557}
558
559#[cfg(feature = "owned-model")]
560impl From<ContractUnionCaseView<'_>> for ContractUnionCase {
561 fn from(value: ContractUnionCaseView<'_>) -> Self {
562 Self {
563 name: to_spec_string(value.name),
564 discriminant: value.discriminant,
565 case_type: value.case_type.into(),
566 }
567 }
568}
569
570#[cfg(feature = "owned-model")]
571impl From<ContractUnionCaseTypeView<'_>> for ContractUnionCaseType {
572 fn from(value: ContractUnionCaseTypeView<'_>) -> Self {
573 match value {
574 ContractUnionCaseTypeView::Void => {
575 ContractUnionCaseType::UnionCaseVoid
576 }
577 ContractUnionCaseTypeView::Tuple(types) => {
578 ContractUnionCaseType::UnionCaseTuple {
579 tuple: types
580 .iter()
581 .copied()
582 .map(Into::into)
583 .collect::<Vec<_>>()
584 .try_into()
585 .unwrap(),
586 }
587 }
588 ContractUnionCaseTypeView::Struct(fields) => {
589 ContractUnionCaseType::UnionCaseStruct {
590 struct_fields: fields
591 .iter()
592 .copied()
593 .map(Into::into)
594 .collect::<Vec<_>>()
595 .try_into()
596 .unwrap(),
597 }
598 }
599 }
600 }
601}
602
603#[cfg(feature = "owned-model")]
604impl From<SpecFragmentView<'_>> for SpecFragment {
605 fn from(value: SpecFragmentView<'_>) -> Self {
606 match value {
607 SpecFragmentView::Interface(fragment) => {
608 SpecFragment::SpecInterface {
609 interface_fragment: fragment.into(),
610 }
611 }
612 SpecFragmentView::Method(fragment) => SpecFragment::SpecMethod {
613 method_fragment: fragment.into(),
614 },
615 SpecFragmentView::TypeDef(def) => SpecFragment::SpecTypeDef {
616 type_def: def.into(),
617 },
618 SpecFragmentView::ExportedTypeDef(def) => {
619 SpecFragment::ExportedSpecTypeDef {
620 type_def: def.into(),
621 }
622 }
623 SpecFragmentView::Event(def) => SpecFragment::SpecEvent {
624 event_def: def.into(),
625 },
626 SpecFragmentView::ExportedEvent(def) => {
627 SpecFragment::ExportedSpecEvent {
628 event_def: def.into(),
629 }
630 }
631 SpecFragmentView::InterfaceAnchor(anchor) => {
632 SpecFragment::InterfaceAnchor {
633 interface_anchor: anchor.into(),
634 }
635 }
636 }
637 }
638}
639
640#[cfg(feature = "owned-model")]
641impl From<SpecInterfaceAnchorView<'_>> for SpecInterfaceAnchor {
642 fn from(value: SpecInterfaceAnchorView<'_>) -> Self {
643 Self {
644 interface_name: to_spec_string(value.interface_name),
645 interface_version: to_spec_string(value.interface_version),
646 declared_by: value.declared_by.into(),
647 }
648 }
649}
650
651#[cfg(feature = "owned-model")]
652impl From<SpecInterfaceFragmentView<'_>> for SpecInterfaceFragment {
653 fn from(value: SpecInterfaceFragmentView<'_>) -> Self {
654 Self {
655 interface_name: to_spec_string(value.interface_name),
656 interface_version: to_spec_string(value.interface_version),
657 declared_by: value.declared_by.into(),
658 throws: value
659 .throws
660 .iter()
661 .copied()
662 .map(Into::into)
663 .collect::<Vec<_>>()
664 .try_into()
665 .unwrap(),
666 emits: value
667 .emits
668 .iter()
669 .copied()
670 .map(Into::into)
671 .collect::<Vec<_>>()
672 .try_into()
673 .unwrap(),
674 }
675 }
676}
677
678#[cfg(feature = "owned-model")]
679impl From<SpecMethodFragmentView<'_>> for SpecMethodFragment {
680 fn from(value: SpecMethodFragmentView<'_>) -> Self {
681 Self {
682 interface_name: to_spec_string(value.interface_name),
683 interface_version: to_spec_string(value.interface_version),
684 declared_by: value.declared_by.into(),
685 method: value.method.into(),
686 }
687 }
688}