mpl_core/hooked/
asset.rs

1#[cfg(feature = "anchor")]
2use anchor_lang::prelude::AnchorSerialize;
3#[cfg(not(feature = "anchor"))]
4use borsh::BorshSerialize;
5
6use std::io::ErrorKind;
7
8use crate::{
9    accounts::{BaseAssetV1, PluginHeaderV1},
10    registry_records_to_external_plugin_adapter_list, registry_records_to_plugin_list,
11    types::Key,
12    Asset, ExternalPluginAdaptersList, PluginRegistryV1Safe, PluginsList,
13};
14
15impl Asset {
16    pub fn deserialize(data: &[u8]) -> Result<Box<Self>, std::io::Error> {
17        if Key::from_slice(data, 0)? != Key::AssetV1 {
18            return Err(ErrorKind::InvalidInput.into());
19        }
20
21        let base = BaseAssetV1::from_bytes(data)?;
22        let base_data = base.try_to_vec()?;
23
24        if base_data.len() != data.len() {
25            return Self::deserialize_with_plugins(data, base, base_data);
26        }
27
28        Ok(Box::new(Self {
29            base,
30            plugin_list: PluginsList::default(),
31            external_plugin_adapter_list: ExternalPluginAdaptersList::default(),
32            plugin_header: None,
33        }))
34    }
35
36    fn deserialize_with_plugins(
37        data: &[u8],
38        base: BaseAssetV1,
39        base_data: Vec<u8>,
40    ) -> Result<Box<Self>, std::io::Error> {
41        let plugin_header = PluginHeaderV1::from_bytes(&data[base_data.len()..])?;
42        let plugin_registry = PluginRegistryV1Safe::from_bytes(
43            &data[plugin_header.plugin_registry_offset as usize..],
44        )?;
45
46        let plugin_list = registry_records_to_plugin_list(&plugin_registry.registry, data)?;
47        let external_plugin_adapter_list = registry_records_to_external_plugin_adapter_list(
48            &plugin_registry.external_registry,
49            data,
50        )?;
51
52        Ok(Box::new(Self {
53            base,
54            plugin_list,
55            external_plugin_adapter_list,
56            plugin_header: Some(plugin_header),
57        }))
58    }
59
60    #[inline(always)]
61    pub fn from_bytes(data: &[u8]) -> Result<Box<Self>, std::io::Error> {
62        Self::deserialize(data)
63    }
64}
65
66impl<'a> TryFrom<&solana_program::account_info::AccountInfo<'a>> for Box<Asset> {
67    type Error = std::io::Error;
68
69    fn try_from(
70        account_info: &solana_program::account_info::AccountInfo<'a>,
71    ) -> Result<Self, Self::Error> {
72        let data: &[u8] = &(*account_info.data).borrow();
73        Asset::deserialize(data)
74    }
75}