ic_query/icrc/model/
token_metadata.rs1use serde::{Deserialize, Serialize};
4use serde_json::Value as JsonValue;
5
6#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
13pub struct IcrcTokenData {
14 pub token_name: String,
16 pub token_symbol: String,
18 pub decimals: u8,
20 pub transfer_fee: String,
22 pub total_supply: String,
24 pub minting_account_owner: Option<String>,
26 pub minting_account_subaccount_hex: Option<String>,
28 pub supported_standards: Vec<IcrcTokenStandardRow>,
30 pub metadata: Vec<IcrcTokenMetadataRow>,
32}
33
34#[cfg_attr(
41 any(feature = "icrc-host", feature = "sns-host"),
42 derive(candid::CandidType)
43)]
44#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
45pub struct IcrcTokenStandardRow {
46 pub name: String,
48 pub url: String,
50}
51
52#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
59pub struct IcrcTokenMetadataRow {
60 pub key: String,
62 pub value_type: IcrcMetadataValueKind,
64 pub value: JsonValue,
66}
67
68#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
75#[serde(rename_all = "snake_case")]
76pub enum IcrcMetadataValueKind {
77 Nat,
79 Int,
81 Text,
83 Blob,
85}
86
87impl IcrcMetadataValueKind {
88 #[must_use]
90 pub const fn as_str(self) -> &'static str {
91 match self {
92 Self::Nat => "nat",
93 Self::Int => "int",
94 Self::Text => "text",
95 Self::Blob => "blob",
96 }
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn metadata_value_kind_labels_round_trip() {
106 for (kind, label) in [
107 (IcrcMetadataValueKind::Nat, "nat"),
108 (IcrcMetadataValueKind::Int, "int"),
109 (IcrcMetadataValueKind::Text, "text"),
110 (IcrcMetadataValueKind::Blob, "blob"),
111 ] {
112 assert_eq!(
113 serde_json::to_string(&kind).unwrap(),
114 format!("\"{label}\"")
115 );
116 assert_eq!(
117 serde_json::from_str::<IcrcMetadataValueKind>(&format!("\"{label}\"")).unwrap(),
118 kind
119 );
120 assert_eq!(kind.as_str(), label);
121 }
122 }
123}