💥 Proposal
Currently, our types models contain two versions of structs: UncheckedFoo and a Foo for each type. This setup is such that we can align with the original rosetta SDK spec.
However, in terms of code quality, and API usage, it leaves much desired.
I suggest we leverage a type state model.
Behind the scenes, the code will still be ugly, but the API usage should be vastly improved as all types will be unified to one struct.
For example:
pub struct Checked;
pub struct Unchecked;
pub struct Foo<State = Unchecked> {
account_ser: Option<Account<Unchecked>>,
account: Option<Account<Checked>>,
size_ser: Option<isize>,
#[serde(skip)]
size: Option<usize>,
state: std::marker::PhantomDate<State>,
}
impl Foo<Unchecked> {
pub fn account(&self) -> Option<&Account<Unchecked>> { self.account_ser.as_ref() }
pub fn size(&self) -> Option<isize> { self.size_ser }
}
impl Foo<Checked> {
pub fn account(&self) -> &Account<Checked> { self.account.as_ref().unwrap() // Can safe unwrap }
pub fn size(&self) -> usize { self.size.unwrap() }
}
The asserter module would then transform the Unchecked version to the Checked version.
The usage of PhantomData should be fine as it's a zero-sized type at the end of the day optimized out of the way by the compiler.
💥 Proposal
Currently, our types models contain two versions of structs:
UncheckedFooand aFoofor each type. This setup is such that we can align with the original rosetta SDK spec.However, in terms of code quality, and API usage, it leaves much desired.
I suggest we leverage a type state model.
Behind the scenes, the code will still be ugly, but the API usage should be vastly improved as all types will be unified to one struct.
For example:
The asserter module would then transform the
Uncheckedversion to theCheckedversion.The usage of
PhantomDatashould be fine as it's a zero-sized type at the end of the day optimized out of the way by the compiler.