hopper_core/accounts/
migrating.rs1use hopper_runtime::error::ProgramError;
8use hopper_runtime::{AccountView, Address};
9
10use crate::account::{FixedLayout, Pod, VerifiedAccount, VerifiedAccountMut};
11use crate::check;
12use crate::check::modifier::HopperLayout;
13use crate::migrate::MigrationKind;
14
15pub struct MigratingAccount<'a, From, To>
21where
22 From: Pod + FixedLayout + HopperLayout,
23 To: Pod + FixedLayout + HopperLayout,
24{
25 view: &'a AccountView,
26 program_id: &'a Address,
27 _from: core::marker::PhantomData<From>,
28 _to: core::marker::PhantomData<To>,
29}
30
31impl<'a, From, To> MigratingAccount<'a, From, To>
32where
33 From: Pod + FixedLayout + HopperLayout,
34 To: Pod + FixedLayout + HopperLayout,
35{
36 #[inline]
38 pub fn from_account(
39 account: &'a AccountView,
40 program_id: &'a Address,
41 ) -> Result<Self, ProgramError> {
42 check::check_owner(account, program_id)?;
43 check::check_writable(account)?;
44 let data = account.try_borrow()?;
45 crate::account::check_header(&data, From::DISC, From::VERSION, &From::LAYOUT_ID)?;
46 check::check_size(&data, From::LEN_WITH_HEADER)?;
47 Ok(Self {
48 view: account,
49 program_id,
50 _from: core::marker::PhantomData,
51 _to: core::marker::PhantomData,
52 })
53 }
54
55 #[inline]
57 pub fn old(&self) -> Result<VerifiedAccount<'a, From>, ProgramError> {
58 let data = self.view.try_borrow()?;
59 VerifiedAccount::from_ref(data)
60 }
61
62 #[inline]
64 pub fn old_mut(&self) -> Result<VerifiedAccountMut<'a, From>, ProgramError> {
65 let data = self.view.try_borrow_mut()?;
66 VerifiedAccountMut::from_ref_mut(data)
67 }
68
69 #[inline]
74 pub fn into_latest(&self) -> Result<VerifiedAccountMut<'a, To>, ProgramError> {
75 let data = self.view.try_borrow_mut()?;
76 crate::account::check_header(&data, To::DISC, To::VERSION, &To::LAYOUT_ID)?;
77 check::check_size(&data, To::LEN_WITH_HEADER)?;
78 VerifiedAccountMut::from_ref_mut(data)
79 }
80
81 #[inline]
85 pub fn migrate_append(&self, payer: &AccountView) -> Result<(), ProgramError> {
86 crate::migrate::migrate_append(
87 self.view,
88 payer,
89 self.program_id,
90 &From::LAYOUT_ID,
91 To::VERSION,
92 &To::LAYOUT_ID,
93 To::DISC,
94 To::LEN_WITH_HEADER,
95 )
96 }
97
98 #[inline]
103 pub fn migration_kind(&self) -> MigrationKind {
104 if To::LEN_WITH_HEADER > From::LEN_WITH_HEADER && To::DISC == From::DISC {
105 MigrationKind::Append
106 } else {
107 MigrationKind::Full
108 }
109 }
110
111 #[inline(always)]
113 pub fn address(&self) -> &Address {
114 self.view.address()
115 }
116
117 #[inline(always)]
119 pub fn to_account_view(&self) -> &'a AccountView {
120 self.view
121 }
122}