db/heromodels/src/models/finance/asset.rs
2025-06-19 13:18:10 +03:00

109 lines
3.2 KiB
Rust

// heromodels/src/models/finance/asset.rs
use heromodels_core::BaseModelData;
use heromodels_derive::model;
use rhai::{CustomType, TypeBuilder};
use serde::{Deserialize, Serialize};
/// AssetType defines the type of blockchain asset
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum AssetType {
Erc20, // ERC-20 token standard
Erc721, // ERC-721 NFT standard
Erc1155, // ERC-1155 Multi-token standard
Native, // Native blockchain asset (e.g., ETH, BTC)
}
impl Default for AssetType {
fn default() -> Self {
AssetType::Native
}
}
/// Asset represents a digital asset or token
#[derive(Debug, Clone, Serialize, Deserialize, CustomType, Default)]
#[model] // Has base.Base in V spec
pub struct Asset {
pub base_data: BaseModelData,
pub name: String, // Name of the asset
pub description: String, // Description of the asset
pub amount: f64, // Amount of the asset
pub address: String, // Address of the asset on the blockchain or bank
pub asset_type: AssetType, // Type of the asset
pub decimals: u8, // Number of decimals of the asset
}
impl Asset {
/// Create a new asset with default values
pub fn new() -> Self {
Self {
base_data: BaseModelData::new(),
name: String::new(),
description: String::new(),
amount: 0.0,
address: String::new(),
asset_type: AssetType::default(),
decimals: 18, // Default for most tokens
}
}
/// Set the name of the asset
pub fn name(mut self, name: impl ToString) -> Self {
self.name = name.to_string();
self
}
/// Set the description of the asset
pub fn description(mut self, description: impl ToString) -> Self {
self.description = description.to_string();
self
}
/// Set the amount of the asset
pub fn amount(mut self, amount: f64) -> Self {
self.amount = amount;
self
}
/// Set the address of the asset on the blockchain
pub fn address(mut self, address: impl ToString) -> Self {
self.address = address.to_string();
self
}
/// Set the type of the asset
pub fn asset_type(mut self, asset_type: AssetType) -> Self {
self.asset_type = asset_type;
self
}
/// Set the number of decimals of the asset
pub fn decimals(mut self, decimals: u8) -> Self {
self.decimals = decimals;
self
}
/// Get the formatted amount with proper decimal places
pub fn formatted_amount(&self) -> String {
let factor = 10_f64.powi(self.decimals as i32);
let formatted_amount = (self.amount * factor).round() / factor;
format!("{:.1$}", formatted_amount, self.decimals as usize)
}
/// Transfer amount to another asset
pub fn transfer_to(&mut self, target: &mut Asset, amount: f64) -> Result<(), &'static str> {
if amount <= 0.0 {
return Err("Transfer amount must be positive");
}
if self.amount < amount {
return Err("Insufficient balance for transfer");
}
self.amount -= amount;
target.amount += amount;
Ok(())
}
}