Skip to main content

ContractTypeSpec

Derive Macro ContractTypeSpec 

Source
#[derive(ContractTypeSpec)]
{
    // Attributes available to this derive:
    #[contract_type_spec]
}
Expand description

Derive ContractTypeSpec (plus ContractTypeRefSpec, a linker anchor, and the raw typedef link-section fragment) for a struct or enum.

§Options

  • #[contract_type_spec(export)] — emit the fragment as an exported typedef, so it survives spec shaking without an inbound reference.
  • #[contract_type_spec(crate = "...")] — resolve the emitted paths through the given crate path instead of ::thruput_sdk.

§crate = "..."

The derive normally emits literal ::thruput_sdk::… paths, so a crate that thruput-sdk itself depends on cannot use it — naming ::thruput_sdk from below thruput-sdk is a dependency cycle. But everything the derive reaches for is a thruput-sdk re-export of a crate below thruput-sdk: __contract_spec is thruput-contract-spec and __xdrs is xdrs. Nothing here is owned by thruput-sdk.

So such a crate can supply a shim matching those two names and point the derive at it:

ⓘ
#[doc(hidden)]
pub mod __sdk_paths {
    pub use thruput_contract_spec as __contract_spec;
    pub use xdrs as __xdrs;
}

#[derive(ContractTypeSpec)]
#[contract_type_spec(crate = "crate::__sdk_paths")]
pub struct U256([u32; 8]);

Note the crate:: prefix. The derive is applied inside the crate that owns the shim, and a crate cannot name itself as ::its_own_name without a separate extern crate self as its_own_name; — spelling it ::thruput_u256::__sdk_paths there fails with E0433. An absolute path is right only when some other crate owns the shim.

The consumer still supplies its own impl ContractTypeName, which the derive references but never emits.

Note this covers spec impls only. #[contract_type] additionally emits impls of traits genuinely owned by thruput-sdk (CollectAuthHandles, ReceiveAuthHandles, MintableType), which a lower crate cannot implement — that is a dependency problem, not a path problem, and has no override.