Skip to main content

thruput_contract_spec/
fragment.rs

1//! Owned raw-spec fragment types.
2//!
3//! `thruputspecraw*` fragments are internal to the SDK toolchain: the
4//! `#[contract]` macros emit them (as const views) and spec-tool parses and
5//! canonicalizes them. Downstream consumers only ever see the finalized
6//! `ContractSpec`, so the fragment types live here rather than in the
7//! protocol-level `thruput-spec` crate.
8//!
9//! These types are the raw wire format. Any change to their encoding — a new
10//! field, a new variant, a reordering — must bump
11//! [`RAW_SPEC_FORMAT`](crate::RAW_SPEC_FORMAT) and its mirrors; see
12//! [`crate::format`]. The stream is unframed, so a consumer that disagrees
13//! about the layout desynchronizes rather than failing cleanly.
14
15use thruput_spec::{
16    ContractEventDef, ContractExceptionType, ContractSpecId,
17    ContractSpecMethod, ContractSpecString, ContractTypeDef,
18};
19use xdrs::*;
20
21#[derive(
22    ReadXDR,
23    WriteXDR,
24    ConstXDRSize,
25    Clone,
26    Debug,
27    PartialEq,
28    Eq,
29    Hash,
30    PartialOrd,
31    Ord,
32)]
33pub struct SpecInterfaceFragment {
34    pub interface_name: ContractSpecString,
35    pub interface_version: ContractSpecString,
36    /// The item that declares this interface: the `#[contract]` trait's spec
37    /// id (`CRATE@MAJOR::module::path::Trait`), or `CRATE@MAJOR` for a bare
38    /// impl or free-function contract. See [`SpecInterfaceAnchor::declared_by`].
39    pub declared_by: ContractSpecId,
40    pub throws: VecM<ContractExceptionType>,
41    pub emits: VecM<ContractSpecId>,
42}
43
44#[derive(
45    ReadXDR,
46    WriteXDR,
47    ConstXDRSize,
48    Clone,
49    Debug,
50    PartialEq,
51    Eq,
52    Hash,
53    PartialOrd,
54    Ord,
55)]
56/// A method belonging to `interface_name`@`interface_version`.
57///
58/// Emitted only by a site that also anchors that interface — a `#[contract]`
59/// impl, or `export_interface_spec!` in a carrier. A `#[contract]` trait
60/// definition emits its [`SpecInterfaceFragment`] as a candidate but no
61/// methods: two unrelated traits can collide on one interface key (default
62/// name = trait ident, default version = crate version), and candidate
63/// methods from a trait nothing implements would otherwise publish as
64/// phantom methods of the contract that merely links them. (`declared_by`
65/// now separates such traits in spec-tool as well.)
66pub struct SpecMethodFragment {
67    pub interface_name: ContractSpecString,
68    pub interface_version: ContractSpecString,
69    /// The item that declares this interface: the `#[contract]` trait's spec
70    /// id (`CRATE@MAJOR::module::path::Trait`), or `CRATE@MAJOR` for a bare
71    /// impl or free-function contract. See [`SpecInterfaceAnchor::declared_by`].
72    pub declared_by: ContractSpecId,
73    pub method: ContractSpecMethod,
74}
75
76#[derive(
77    ReadXDR,
78    WriteXDR,
79    ConstXDRSize,
80    Clone,
81    Debug,
82    PartialEq,
83    Eq,
84    Hash,
85    PartialOrd,
86    Ord,
87)]
88pub struct SpecInterfaceAnchor {
89    pub interface_name: ContractSpecString,
90    pub interface_version: ContractSpecString,
91    /// The item that declares the anchored interface: the `#[contract]`
92    /// trait's spec id (`CRATE@MAJOR::module::path::Trait`), or `CRATE@MAJOR`
93    /// for a bare impl or free-function contract.
94    ///
95    /// The interface *key* is (name, version) because that is all the wire
96    /// carries — `interface_id` and every entrypoint id hash the bare name
97    /// and major version, so that independent crates can implement one
98    /// interface. Two unrelated traits can therefore share a key. This field
99    /// is spec-only and tells them apart: spec-tool keeps only the fragments
100    /// of the declarer an artifact anchors, and rejects an artifact that
101    /// anchors two declarers under one key, since nothing on the wire could
102    /// tell their interfaces apart.
103    pub declared_by: ContractSpecId,
104}
105
106#[derive(
107    ReadXDR,
108    WriteXDR,
109    ConstXDRSize,
110    Clone,
111    Debug,
112    PartialEq,
113    Eq,
114    Hash,
115    PartialOrd,
116    Ord,
117)]
118#[repr(i32)]
119pub enum SpecFragment {
120    SpecInterface {
121        interface_fragment: SpecInterfaceFragment,
122    } = 0,
123    SpecMethod {
124        method_fragment: SpecMethodFragment,
125    } = 1,
126    SpecTypeDef {
127        type_def: ContractTypeDef,
128    } = 2,
129    ExportedSpecTypeDef {
130        type_def: ContractTypeDef,
131    } = 3,
132    SpecEvent {
133        event_def: ContractEventDef,
134    } = 4,
135    ExportedSpecEvent {
136        event_def: ContractEventDef,
137    } = 5,
138    InterfaceAnchor {
139        interface_anchor: SpecInterfaceAnchor,
140    } = 6,
141}