use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcTokenData {
pub token_name: String,
pub token_symbol: String,
pub decimals: u8,
pub transfer_fee: String,
pub total_supply: String,
pub minting_account_owner: Option<String>,
pub minting_account_subaccount_hex: Option<String>,
pub supported_standards: Vec<IcrcTokenStandardRow>,
pub metadata: Vec<IcrcTokenMetadataRow>,
}
#[cfg_attr(
any(feature = "icrc-host", feature = "sns-host"),
derive(ic_platform::candid::contract::CandidType)
)]
#[cfg_attr(
any(feature = "icrc-host", feature = "sns-host"),
candid_path("ic_platform::candid::contract")
)]
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct IcrcTokenStandardRow {
pub name: String,
pub url: String,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcTokenMetadataRow {
pub key: String,
pub value_type: IcrcMetadataValueKind,
pub value: JsonValue,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum IcrcMetadataValueKind {
Nat,
Int,
Text,
Blob,
}
impl IcrcMetadataValueKind {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Nat => "nat",
Self::Int => "int",
Self::Text => "text",
Self::Blob => "blob",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn metadata_value_kind_labels_round_trip() {
for (kind, label) in [
(IcrcMetadataValueKind::Nat, "nat"),
(IcrcMetadataValueKind::Int, "int"),
(IcrcMetadataValueKind::Text, "text"),
(IcrcMetadataValueKind::Blob, "blob"),
] {
assert_eq!(
serde_json::to_string(&kind).unwrap(),
format!("\"{label}\"")
);
assert_eq!(
serde_json::from_str::<IcrcMetadataValueKind>(&format!("\"{label}\"")).unwrap(),
kind
);
assert_eq!(kind.as_str(), label);
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum IcrcIndexData {
Found(String),
Unavailable(String),
}