Skip to main content

mpl_core/hooked/
asset.rs

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