Translates pretty well (from_slice is lacking some RC related checks just PoC code):
pub struct TpmRcCast<'a>(TpmUint32<'a>);
impl<'a> crate::TpmCast<'a> for TpmRcCast<'a> {
fn from_slice(slice: &'a [u8]) -> TpmResult<Self> {
Ok(TpmRcCast(TpmUint32::from_slice(slice)?))
}
fn as_slice(&self) -> &'a [u8] {
self.0.as_slice()
}
}
In the end of the day this is superior despite adding up a new trick to my sack of random macro hacks:
tpm_integer!(u8, TpmUint8, Unsigned);
tpm_integer!(i8, TpmInt8, Signed);
tpm_integer!(u16, TpmUint16, Unsigned);
tpm_integer!(i32, TpmInt32, Signed);
tpm_integer!(u32, TpmUint32, Unsigned);
tpm_integer!(u64, TpmUint64, Unsigned);
Now the names match TCG specification names, and they are also first fully zerocopy migrated types. This way previously redundant looking field now is actually self-documenting field.
Other zerocopy types will get the nasty “Cast” postfix up until migration is complete (e.g., TpmBufferCast).
For the record, the last field is used to address exactly one quirk related to TCG specs: TPM_CLOCK_TIME
, meaning that “invalid discriminant error” needs too versions :-/
I’m sure we would get numbers going from zero to six, and “get this complex science” as e.g., most of have ability to read, and understand nuances such as the difference between slower and faster… This is DailyWTF proximity enough level bad definition that I tend to like that TPM_CLOCK_TIME exist…
Great now I think I have solid base traits in place i.e., TpmCast, TpmCastMut, TpmHasCast and TpmHasCastMut:
I also relaxed the contribution guidelines just a little bit:
//! * `alloc` is disallowed.
//! * Dependencies are disallowed.
//! * Developer dependencies are disallowed.
-//! * Panics are disallowed.
+//! * Panics are allowed disallowed by default, except concrete type casts in
+//! `TpmCast::as_slice` is allowed to use `unwrap` as long as
+//! `TpmCast::from_slice` meets the documented contract.
This starts to “feel right” when it comes to “zerocopy”:
pub trait TpmCast<'a>: Sized {
fn cast(slice: &'a [u8]) -> TpmResult<Self>;
fn as_slice(&self) -> &'a [u8];
}
And pretty analogus to pre-existing TpmBuild and TpmParse i.e., they provide clone semantics and this is like hierarchical pointer.
It’s pretty easy to squeeze in because I only really have to edit macros for the most part. I have already basic types, and buffers and lists will follow the same patterns.