Structs and enums
hacspec also supports user-defined structs and enums with some restrictions.
Structs
The only form of struct declaration currently allowed in hacspec is:
struct Foo(u32, Seq<u32>);
The struct thus declared can have one or more components. This form of struct declaration effectively corresponds to a single-case enum, and is implemented as such. Struct components can be accessed through let-binding destructuring:
let Foo(x, y) = z;
Note that you can't store borrowed types inside hacspec structs, hence there is no need for lifetime variables.
Enums
hacspec supports very restricted enum
declarations:
enum Foo {
CaseA,
CaseB(u16),
CaseC(Seq<bool>, u64)
}
These declaration don't support the basic Rust features such as C-style union declarations with assignments for each case.
Enumeration values can be pattern-matched in an expression:
match x {
Foo::CaseA => ...,
Foo::CaseB(y) => ...,
Foo::CaseC(y,z) => ...
}
Note that you can't store borrowed types inside hacspec enums, hence there is no need for lifetime variables.
Option and Result
User-defined structs and enums presented above don't support generic type
parameters yet. However, the built-in enums Option<T>
and Result<T,U>
support type parameters. Those type parameters have to be explicitly declared
each time, as hacspec does not currently support type inference:
match x {
Result::<Seq<u8>, bool>::Ok(y) => ...,
Result::<Seq<u8>, bool>::Err(err) => ...
}
Such type parameter declaration is cumbersome; as a workaround we advise to declare a type alias as such:
type MyResult = Result::<Seq<u8>, bool>;