#[derive(ScryptoSborAssertion)]
{
// Attributes available to this derive:
#[sbor_assert]
}
Expand description
A macro for outputting tests and marker traits to assert that a type has maintained its shape over time.
There are two types of assertion modes:
fixed
mode is used to ensure that a type is unchanged.backwards_compatible
mode is used when multiple versions of the type are permissible, but newer versions of the type must be compatible with the older version where they align. This mode (A) ensures that the type’s current schema is equivalent to the latest version, and (B) ensures that each of the schemas is a strict extension of the previous mode.
§Initial schema generation and regeneration
To output a generated schema, temporarily add a generate
parameter or a regenerate
parameter,
after the fixed
or backwards_compatible
parameter, and then run the created test.
If using Rust Analyzer this can be run from the IDE, or it can be run via cargo test
.
To protect against accidentally doing the wrong thing, generate
can only be used for initial generation,
whereas regenerate
can only be used for replacing an existing generation.
If a “FILE:..” path is specified, it will (re)generate that file, else it will output to the console:
- In
fixed
mode, this will (re)generate against the given schema location. - In
backwards_compatible
mode, this will (re)generate against the latest schema location (the last in the list).
The test will then panic to ensure it fails, and can’t be left accidentally in (re)generate state.
#[derive(ScryptoSbor, ScryptoSborAssertion)]
#[sbor_assert(fixed("FILE:MyType-schema-v1.bin"), generate)]
struct MyType {
// ...
}
§Fixed schema verification
To verify the type’s schema is unchanged, do:
#[derive(ScryptoSbor, ScryptoSborAssertion)]
#[sbor_assert(fixed("FILE:MyType-schema-v1.bin"))]
struct MyType {
// ...
}
Instead of "FILE:X"
, you can also use "INLINE:<hex>"
, "CONST:<Constant>"
or "EXPR:<Expression>"
where the expression (such as generate_schema()
) has to generate a SingleTypeSchema<NoCustomSchema>
.
§Backwards compatibility verification
To allow multiple backwards-compatible versions, you can do this:
#[derive(ScryptoSbor, ScryptoSborAssertion)]
#[sbor_assert(backwards_compatible(
version1 = "FILE:MyType-schema-v1.bin",
version2 = "FILE:MyType-schema-v2.bin",
))]
struct MyType {
// ...
}
Instead of "FILE:X.bin"
, you can also use "FILE:X.txt"
, "INLINE:<hex>"
, "CONST:<Constant>"
or "EXPR:<Expression>"
where the expression (such as generate_schema()
) has to generate a SingleTypeSchema<ScryptoCustomSchema>
.
If you wish to configure exactly which schemas are used for comparison of the current schema with the latest named schema; and each named schema with its predecessor, you can use:
#[derive(ScryptoSbor, ScryptoSborAssertion)]
#[sbor_assert(backwards_compatible("EXPR:<Expression>"))
struct MyType {
// ...
}
Where the expression (such as params_builder()
) has to generate a SingleTypeSchemaCompatibilityParameters<ScryptoCustomSchema>
.
§Custom settings
By default, the fixed
mode will use SchemaComparisonSettings::require_equality()
and
the backwards_compatible
mode will use SchemaComparisonSettings::require_equality()
for the check
of current
aginst the latest version, and SchemaComparisonSettings::allow_extension()
for the
checks between consecutive versions.
You may wish to change these:
- If you just wish to ignore the equality of metadata such as names, you can use the
allow_name_changes
flag. - If you wish to override all settings, you can provide a constant containing your own SchemaComparisonSettings.
- If you wish to specify a builder for settings, you can provide
"EXPR:|builder| builder.<stuff>"
- If for
backwards_compatible
, you wish to provide a separate configuration for the “latest” and “named versions” checks, you can usesettings(comparison_between_versions = \"EXPR:F1\", comparison_between_current_and_latest = \"EXPR:F2\")
For example:
#[derive(ScryptoSbor, ScryptoSborAssertion)]
#[sbor_assert(
fixed("FILE:MyType-schema-v1.bin"),
settings(allow_name_changes),
)]
struct MyType {
// ...
}
#[derive(ScryptoSbor, ScryptoSborAssertion)]
#[sbor_assert(
backwards_compatible(
v1 = "FILE:MyType-schema-v1.bin",
v2 = "FILE:MyType-schema-v2.bin",
),
settings(
// We allow name changes between versions, but require the current schema to exactly match
// the latest version (v2 in this case).
// This could be useful to e.g. ensure that we have a fixed schema with the latest naming available.
comparison_between_versions = "EXPR: |s| s.allow_all_name_changes()",
comparison_between_current_and_latest = "EXPR: |s| s",
),
)]
struct MyType {
// ...
}