miden_objects/conversion/
asset.rs1use alloc::format;
2
3use miden_protocol::asset::{Asset, AssetClass, AssetComposition, AssetId};
4
5use super::{MessageDecodeExt, required};
6use crate::{ConversionError, ConversionResultExt, proto};
7
8impl From<&AssetClass> for proto::asset::AssetClass {
9 fn from(asset_class: &AssetClass) -> Self {
10 Self {
11 suffix: Some(asset_class.suffix().into()),
12 prefix: Some(asset_class.prefix().into()),
13 }
14 }
15}
16
17impl From<AssetClass> for proto::asset::AssetClass {
18 fn from(asset_class: AssetClass) -> Self {
19 Self::from(&asset_class)
20 }
21}
22
23impl TryFrom<proto::asset::AssetClass> for AssetClass {
24 type Error = ConversionError;
25
26 fn try_from(message: proto::asset::AssetClass) -> Result<Self, Self::Error> {
27 let decoder = message.decoder();
28 let suffix = required!(decoder, message.suffix)?;
29 let prefix = required!(decoder, message.prefix)?;
30
31 Ok(Self::new(suffix, prefix))
32 }
33}
34
35fn decode_asset_composition(composition: i32) -> Result<AssetComposition, ConversionError> {
36 match proto::asset::AssetComposition::try_from(composition) {
37 Ok(proto::asset::AssetComposition::None) => Ok(AssetComposition::None),
38 Ok(proto::asset::AssetComposition::Fungible) => Ok(AssetComposition::Fungible),
39 Ok(proto::asset::AssetComposition::Custom) => Ok(AssetComposition::Custom),
40 Ok(proto::asset::AssetComposition::Unspecified) => {
41 Err(ConversionError::message("asset composition is unspecified"))
42 },
43 Err(error) => Err(ConversionError::with_source(
44 format!("unknown asset composition {composition}"),
45 error,
46 )),
47 }
48}
49
50fn decode_asset_version(version: i32) -> Result<(), ConversionError> {
51 match proto::asset::AssetVersion::try_from(version) {
52 Ok(proto::asset::AssetVersion::V1) => Ok(()),
53 Ok(proto::asset::AssetVersion::Unspecified) => {
54 Err(ConversionError::message("asset id version is unspecified"))
55 },
56 Err(error) => Err(ConversionError::with_source(
57 format!("unknown asset id version {version}"),
58 error,
59 )),
60 }
61}
62
63fn encode_asset_composition(composition: AssetComposition) -> i32 {
64 match composition {
65 AssetComposition::None => proto::asset::AssetComposition::None as i32,
66 AssetComposition::Fungible => proto::asset::AssetComposition::Fungible as i32,
67 AssetComposition::Custom => proto::asset::AssetComposition::Custom as i32,
68 }
69}
70
71impl From<&AssetId> for proto::asset::AssetId {
72 fn from(asset_id: &AssetId) -> Self {
73 Self {
74 version: proto::asset::AssetVersion::V1 as i32,
75 asset_class: Some(asset_id.asset_class().into()),
76 composition: encode_asset_composition(asset_id.composition()),
77 faucet_id: Some(asset_id.faucet_id().into()),
78 }
79 }
80}
81
82impl From<AssetId> for proto::asset::AssetId {
83 fn from(asset_id: AssetId) -> Self {
84 Self::from(&asset_id)
85 }
86}
87
88impl TryFrom<proto::asset::AssetId> for AssetId {
89 type Error = ConversionError;
90
91 fn try_from(message: proto::asset::AssetId) -> Result<Self, Self::Error> {
92 decode_asset_version(message.version).context("version")?;
93
94 let decoder = message.decoder();
95 let asset_class = required!(decoder, message.asset_class)?;
96 let composition = decode_asset_composition(message.composition).context("composition")?;
97 let faucet_id = required!(decoder, message.faucet_id)?;
98
99 Self::new(asset_class, faucet_id, composition).map_err(ConversionError::new)
100 }
101}
102
103impl From<&Asset> for proto::asset::Asset {
104 fn from(asset: &Asset) -> Self {
105 Self {
106 asset_id: Some(asset.id().into()),
107 value: Some(asset.to_value_word().into()),
108 }
109 }
110}
111
112impl From<Asset> for proto::asset::Asset {
113 fn from(asset: Asset) -> Self {
114 Self::from(&asset)
115 }
116}
117
118impl TryFrom<proto::asset::Asset> for Asset {
119 type Error = ConversionError;
120
121 fn try_from(message: proto::asset::Asset) -> Result<Self, Self::Error> {
122 let decoder = message.decoder();
123 let asset_id = required!(decoder, message.asset_id)?;
124 let value = required!(decoder, message.value)?;
125
126 Self::new(asset_id, value).map_err(ConversionError::new)
127 }
128}