1#![no_std]
3
4use vstd::prelude::*;
5
6use core::mem::MaybeUninit;
7
8verus! {
9
10pub unsafe trait Pod: Copy + Sized {
25 #[verifier::external_body]
27 fn new_zeroed() -> Self {
28 unsafe { core::mem::zeroed() }
30 }
31
32 #[verifier::external_body]
34 fn new_uninit() -> Self {
35 #[allow(clippy::uninit_assumed_init)]
37 unsafe { MaybeUninit::uninit().assume_init() }
38 }
39
40 #[verus_spec(
42 requires
43 bytes@.len() >= core::mem::size_of::<Self>(),
44 returns
45 from_bytes_spec::<Self>(bytes@),
46 )]
47 fn from_bytes(bytes: &[u8]) -> Self {
48 let mut new_self = Self::new_uninit();
49 let copy_len = new_self.as_bytes().len();
50 new_self.as_bytes_mut().copy_from_slice(&bytes[..copy_len]);
51 proof {
52 assert(new_self == decode_pod::<Self>(bytes@[0..core::mem::size_of::<Self>()]));
53 }
54 new_self
55 }
56
57 #[verifier::external_body]
59 #[verus_spec(r =>
60 ensures
61 r.len() == core::mem::size_of::<Self>(),
62 r@ == pod_bytes(*self),
63 )]
64 fn as_bytes(&self) -> &[u8] {
65 let ptr = self as *const Self as *const u8;
66 let len = core::mem::size_of::<Self>();
67 unsafe { core::slice::from_raw_parts(ptr, len) }
68 }
69
70 #[verifier::external_body]
72 #[verus_spec(r =>
73 ensures
74 r.len() == core::mem::size_of::<Self>(),
75 final(r)@ == pod_bytes(*final(self)),
76 *final(self) == decode_pod::<Self>(final(r)@),
77 )]
78 fn as_bytes_mut(&mut self) -> &mut [u8] {
79 let ptr = self as *mut Self as *mut u8;
80 let len = core::mem::size_of::<Self>();
81 unsafe { core::slice::from_raw_parts_mut(ptr, len) }
82 }
83}
84
85pub open spec fn from_bytes_spec<T>(bytes: Seq<u8>) -> T {
87 decode_pod::<T>(bytes[0..core::mem::size_of::<T>()])
88}
89
90pub uninterp spec fn pod_bytes<T>(val: T) -> Seq<u8>;
96
97pub open spec fn decode_pod<T>(bytes: Seq<u8>) -> T {
103 choose|val: T| pod_bytes::<T>(val) == bytes
104}
105
106macro_rules! impl_pod_for {
107 ($($pod_ty:ty),*) => {
108 $(unsafe impl Pod for $pod_ty {})*
109 };
110}
111
112impl_pod_for!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, isize, usize);
114
115unsafe impl<T: Pod, const N: usize> Pod for [T; N] {
117
118}
119
120} #[cfg(feature = "derive")]
122pub use ostd_pod_derive::*;