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}