pallet_assets/
extra_mutator.rs1use super::*;
21
22pub struct ExtraMutator<T: Config<I>, I: 'static = ()> {
29 id: T::AssetId,
30 who: T::AccountId,
31 original: T::Extra,
32 pending: Option<T::Extra>,
33}
34
35impl<T: Config<I>, I: 'static> Drop for ExtraMutator<T, I> {
36 fn drop(&mut self) {
37 debug_assert!(self.commit().is_ok(), "attempt to write to non-existent asset account");
38 }
39}
40
41impl<T: Config<I>, I: 'static> core::ops::Deref for ExtraMutator<T, I> {
42 type Target = T::Extra;
43 fn deref(&self) -> &T::Extra {
44 match self.pending {
45 Some(ref value) => value,
46 None => &self.original,
47 }
48 }
49}
50
51impl<T: Config<I>, I: 'static> core::ops::DerefMut for ExtraMutator<T, I> {
52 fn deref_mut(&mut self) -> &mut T::Extra {
53 if self.pending.is_none() {
54 self.pending = Some(self.original.clone());
55 }
56 self.pending.as_mut().unwrap()
57 }
58}
59
60impl<T: Config<I>, I: 'static> ExtraMutator<T, I> {
61 pub(super) fn maybe_new(
62 id: T::AssetId,
63 who: impl core::borrow::Borrow<T::AccountId>,
64 ) -> Option<ExtraMutator<T, I>> {
65 if let Some(a) = Account::<T, I>::get(&id, who.borrow()) {
66 Some(ExtraMutator::<T, I> {
67 id,
68 who: who.borrow().clone(),
69 original: a.extra,
70 pending: None,
71 })
72 } else {
73 None
74 }
75 }
76
77 pub fn commit(&mut self) -> Result<(), ()> {
79 if let Some(extra) = self.pending.take() {
80 Account::<T, I>::try_mutate(&self.id, &self.who, |maybe_account| {
81 maybe_account.as_mut().ok_or(()).map(|account| account.extra = extra)
82 })
83 } else {
84 Ok(())
85 }
86 }
87
88 pub fn revert(mut self) -> Result<(), ()> {
90 self.pending = None;
91 Account::<T, I>::try_mutate(&self.id, &self.who, |maybe_account| {
92 maybe_account
93 .as_mut()
94 .ok_or(())
95 .map(|account| account.extra = self.original.clone())
96 })
97 }
98}