109 lines
3.2 KiB
Rust
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(())
|
|
}
|
|
}
|