123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- use crate::{amount::AmountCents, asset::AssetId, Amount, Asset, Error};
- use std::{collections::HashMap, sync::Arc};
- /// Asset manager
- ///
- /// The Verax asset manager is a simple structure that holds the list of
- /// supported assets.
- ///
- /// The asset manager is used to convert from human readable amounts to an
- /// internal representation which is safe to use and operate.
- #[derive(Clone, Debug, Eq, PartialEq)]
- pub struct AssetManager {
- assets: Arc<HashMap<AssetId, AssetDefinition>>,
- asset_names: Arc<HashMap<Arc<str>, AssetDefinition>>,
- }
- /// The asset definition
- ///
- /// It is a simple structure that holds the asset id (an internal number), name
- /// (a human name) and the asset precision.
- #[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize)]
- pub struct AssetDefinition {
- /// The asset definition
- #[serde(flatten)]
- pub asset: Asset,
- #[serde(
- serialize_with = "crate::serialize_arc_str",
- deserialize_with = "crate::deserialize_arc_str"
- )]
- name: Arc<str>,
- }
- impl AssetManager {
- /// Creates a new instance of the asset manager
- pub fn new(assets: Vec<AssetDefinition>) -> Self {
- Self {
- assets: Arc::new(
- assets
- .iter()
- .map(|asset| (asset.asset.id, asset.clone()))
- .collect(),
- ),
- asset_names: Arc::new(
- assets
- .into_iter()
- .map(|asset| (asset.name.clone(), asset))
- .collect(),
- ),
- }
- }
- /// Get the name of an asset by their asset id
- pub fn get_name(&self, id: AssetId) -> Result<Arc<str>, Error> {
- self.assets
- .get(&id)
- .map(|asset| asset.name.clone())
- .ok_or(Error::AssetIdNotFound(id))
- }
- /// Get an asset definition by their id
- pub fn asset(&self, id: AssetId) -> Result<Asset, Error> {
- self.assets
- .get(&id)
- .map(|asset| asset.asset.clone())
- .ok_or(Error::AssetIdNotFound(id))
- }
- /// Get an asset definition by their human name
- pub fn human_amount_by_name(&self, name: &str, human_amount: &str) -> Result<Amount, Error> {
- Ok(self
- .asset_names
- .get(name)
- .map(|asset| Amount::from_human(asset.asset.clone(), human_amount))
- .ok_or(Error::AssetNotFound(name.to_owned()))??)
- }
- /// Get an Amount by their asset Id and cents
- pub fn amount_by_and_cents(&self, id: AssetId, cents: AmountCents) -> Result<Amount, Error> {
- self.asset(id).map(|asset| Amount::new(asset, cents))
- }
- }
- impl AssetDefinition {
- /// Creates a new asset definition
- pub fn new(id: u32, name: &str, precision: u8) -> Self {
- let name: Arc<str> = name.into();
- Self {
- asset: Asset {
- id,
- precision,
- name: name.clone(),
- },
- name,
- }
- }
- }
|