1
0

mod.rs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. use pinocchio::program_error::ProgramError;
  2. pub mod account;
  3. pub mod account_state;
  4. pub mod mint;
  5. pub mod multisig;
  6. /// Type alias for fields represented as `COption`.
  7. pub type COption<T> = ([u8; 4], T);
  8. /// Marker trait for types that can be cast from a raw pointer.
  9. ///
  10. /// # Safety
  11. ///
  12. /// It is up to the type implementing this trait to guarantee that the cast is
  13. /// safe, i.e., the fields of the type are well aligned and there are no padding
  14. /// bytes.
  15. pub unsafe trait Transmutable {
  16. /// The length of the type.
  17. ///
  18. /// This must be equal to the size of each individual field in the type.
  19. const LEN: usize;
  20. }
  21. /// Trait to represent a type that can be initialized.
  22. pub trait Initializable {
  23. /// Return `true` if the object is initialized.
  24. fn is_initialized(&self) -> Result<bool, ProgramError>;
  25. }
  26. /// Return a reference for an initialized `T` from the given bytes.
  27. ///
  28. /// # Safety
  29. ///
  30. /// The caller must ensure that `bytes` contains a valid representation of `T`.
  31. #[inline(always)]
  32. pub unsafe fn load<T: Initializable + Transmutable>(bytes: &[u8]) -> Result<&T, ProgramError> {
  33. load_unchecked(bytes).and_then(|t: &T| {
  34. // checks if the data is initialized
  35. if t.is_initialized()? {
  36. Ok(t)
  37. } else {
  38. Err(ProgramError::UninitializedAccount)
  39. }
  40. })
  41. }
  42. /// Return a `T` reference from the given bytes.
  43. ///
  44. /// This function does not check if the data is initialized.
  45. ///
  46. /// # Safety
  47. ///
  48. /// The caller must ensure that `bytes` contains a valid representation of `T`.
  49. #[inline(always)]
  50. pub unsafe fn load_unchecked<T: Transmutable>(bytes: &[u8]) -> Result<&T, ProgramError> {
  51. if bytes.len() != T::LEN {
  52. return Err(ProgramError::InvalidAccountData);
  53. }
  54. Ok(&*(bytes.as_ptr() as *const T))
  55. }
  56. /// Return a mutable reference for an initialized `T` from the given bytes.
  57. ///
  58. /// # Safety
  59. ///
  60. /// The caller must ensure that `bytes` contains a valid representation of `T`.
  61. #[inline(always)]
  62. pub unsafe fn load_mut<T: Initializable + Transmutable>(
  63. bytes: &mut [u8],
  64. ) -> Result<&mut T, ProgramError> {
  65. load_mut_unchecked(bytes).and_then(|t: &mut T| {
  66. // checks if the data is initialized
  67. if t.is_initialized()? {
  68. Ok(t)
  69. } else {
  70. Err(ProgramError::UninitializedAccount)
  71. }
  72. })
  73. }
  74. /// Return a mutable `T` reference from the given bytes.
  75. ///
  76. /// This function does not check if the data is initialized.
  77. ///
  78. /// # Safety
  79. ///
  80. /// The caller must ensure that `bytes` contains a valid representation of `T`.
  81. #[inline(always)]
  82. pub unsafe fn load_mut_unchecked<T: Transmutable>(
  83. bytes: &mut [u8],
  84. ) -> Result<&mut T, ProgramError> {
  85. if bytes.len() != T::LEN {
  86. return Err(ProgramError::InvalidAccountData);
  87. }
  88. Ok(&mut *(bytes.as_mut_ptr() as *mut T))
  89. }