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}