use chrono::{Duration, Utc}; use heromodels::db::{Collection, Db}; use heromodels::models::finance::asset::AssetType; use heromodels::models::finance::marketplace::{Bid, Listing, ListingType}; use heromodels_core::Model; // Helper function to print listing details fn print_listing_details(listing: &Listing) { println!("\n--- Listing Details ---"); println!("ID: {}", listing.get_id()); println!("Title: {}", listing.title); println!("Description: {}", listing.description); println!("Asset ID: {}", listing.asset_id); println!("Asset Type: {:?}", listing.asset_type); println!("Seller ID: {}", listing.seller_id); println!("Price: {} {}", listing.price, listing.currency); println!("Listing Type: {:?}", listing.listing_type); println!("Status: {:?}", listing.status); if let Some(expires_at) = listing.expires_at { println!("Expires At: {}", expires_at); } else { println!("Expires At: Never"); } if let Some(sold_at) = listing.sold_at { println!("Sold At: {}", sold_at); } if let Some(buyer_id) = &listing.buyer_id { println!("Buyer ID: {}", buyer_id); } if let Some(sale_price) = listing.sale_price { println!("Sale Price: {} {}", sale_price, listing.currency); } println!("Bids: {}", listing.bids.len()); println!("Tags: {:?}", listing.tags); if let Some(image_url) = &listing.image_url { println!("Image URL: {}", image_url); } println!("Created At: {}", listing.base_data.created_at); println!("Modified At: {}", listing.base_data.modified_at); } // Helper function to print bid details fn print_bid_details(bid: &Bid) { println!("\n--- Bid Details ---"); println!("Listing ID: {}", bid.listing_id); println!("Bidder ID: {}", bid.bidder_id); println!("Amount: {} {}", bid.amount, bid.currency); println!("Status: {:?}", bid.status); println!("Created At: {}", bid.created_at); } fn main() { // Create a new DB instance in /tmp/marketplace_db, and reset before every run let db = heromodels::db::hero::OurDB::new("/tmp/marketplace_db", true).expect("Can create DB"); println!("Hero Models - Marketplace Example"); println!("================================"); // Create listings with auto-generated IDs // Fixed price listing let fixed_price_listing = Listing::new( None, // Auto-generated ID "Vintage Guitar", "A beautiful vintage guitar in excellent condition", "asset123", AssetType::Erc721, // NFT representing a physical item "seller456", 1200.0, "USD", ListingType::FixedPrice, Some(Utc::now() + Duration::days(30)), // Expires in 30 days vec![ "music".to_string(), "instrument".to_string(), "vintage".to_string(), ], Some("https://example.com/images/vintage_guitar.jpg"), ); // Auction listing let auction_listing = Listing::new( None, // Auto-generated ID "Rare Painting", "A rare painting from the 19th century", "asset789", AssetType::Erc721, // NFT representing a physical item "seller456", 5000.0, // Starting price "USD", ListingType::Auction, Some(Utc::now() + Duration::days(7)), // Auction ends in 7 days vec![ "art".to_string(), "painting".to_string(), "antique".to_string(), ], Some("https://example.com/images/rare_painting.jpg"), ); // Exchange listing let exchange_listing = Listing::new( None, // Auto-generated ID "Digital Artwork NFT", "A unique digital artwork as an NFT", "asset101", AssetType::Erc1155, // Multi-token for digital art "seller789", 0.5, // Price in ETH "ETH", ListingType::Exchange, Some(Utc::now() + Duration::days(14)), // Expires in 14 days vec!["digital".to_string(), "nft".to_string(), "art".to_string()], Some("https://example.com/images/digital_artwork.jpg"), ); // Save all listings to database and get their assigned IDs and updated models let (fixed_price_id, db_fixed_price) = db .collection() .expect("can open listing collection") .set(&fixed_price_listing) .expect("can set listing"); let (auction_id, db_auction) = db .collection() .expect("can open listing collection") .set(&auction_listing) .expect("can set listing"); let (exchange_id, db_exchange) = db .collection() .expect("can open listing collection") .set(&exchange_listing) .expect("can set listing"); println!("Fixed Price Listing assigned ID: {}", fixed_price_id); println!("Auction Listing assigned ID: {}", auction_id); println!("Exchange Listing assigned ID: {}", exchange_id); // Print all listings retrieved from database println!("\n--- Listings Retrieved from Database ---"); println!("\n1. Fixed Price Listing:"); print_listing_details(&db_fixed_price); println!("\n2. Auction Listing:"); print_listing_details(&db_auction); println!("\n3. Exchange Listing:"); print_listing_details(&db_exchange); // Demonstrate working with bids on an auction listing println!("\n--- Working with Bids ---"); // Create bids for the auction listing let bid1 = Bid::new( auction_id, 101, // Bidder ID 5200.0, "USD", ); let bid2 = Bid::new( auction_id, 102, // Bidder ID 5500.0, "USD", ); // Print the bids println!("\n1. First Bid:"); print_bid_details(&bid1); println!("\n2. Second Bid:"); print_bid_details(&bid2); // Add bids to the auction listing let updated_auction = db_auction .add_bid(bid1.clone()) .expect("can add first bid") .add_bid(bid2.clone()) .expect("can add second bid"); // Save the updated auction listing let (_, db_updated_auction) = db .collection() .expect("can open listing collection") .set(&updated_auction) .expect("can set updated auction"); println!("\n3. Auction Listing After Adding Bids:"); print_listing_details(&db_updated_auction); // Demonstrate retrieving the highest bid if let Some(highest_bid) = db_updated_auction.highest_bid() { println!("\n4. Highest Bid:"); print_bid_details(highest_bid); } // Demonstrate completing a sale for the fixed price listing println!("\n--- Completing a Sale ---"); // Complete the fixed price listing sale let completed_fixed_price = db_fixed_price .complete_sale("buyer123", 1200.0) .expect("can complete sale"); // Save the updated listing let (_, db_completed_fixed_price) = db .collection() .expect("can open listing collection") .set(&completed_fixed_price) .expect("can set completed listing"); println!("\n1. Fixed Price Listing After Sale:"); print_listing_details(&db_completed_fixed_price); // Demonstrate completing an auction println!("\n--- Completing an Auction ---"); // Complete the auction with the highest bidder // Store the bidder_id and amount before moving db_updated_auction let bidder_id = db_updated_auction.highest_bid().unwrap().bidder_id; let amount = db_updated_auction.highest_bid().unwrap().amount; // Now complete the sale let completed_auction = db_updated_auction .complete_sale(bidder_id.to_string(), amount) .expect("can complete auction"); // Save the updated auction listing let (_, db_completed_auction) = db .collection() .expect("can open listing collection") .set(&completed_auction) .expect("can set completed auction"); println!("\n1. Auction Listing After Completion:"); print_listing_details(&db_completed_auction); // Demonstrate cancelling a listing println!("\n--- Cancelling a Listing ---"); // Cancel the exchange listing let cancelled_exchange = db_exchange.cancel().expect("can cancel listing"); // Save the updated listing let (_, db_cancelled_exchange) = db .collection() .expect("can open listing collection") .set(&cancelled_exchange) .expect("can set cancelled listing"); println!("\n1. Exchange Listing After Cancellation:"); print_listing_details(&db_cancelled_exchange); // Demonstrate checking for expired listings println!("\n--- Checking for Expired Listings ---"); // Create a listing that's already expired let expired_listing = Listing::new( None, // Auto-generated ID "Already Expired Item", "This item's listing has already expired", "asset202", AssetType::Erc721, // NFT representing a physical item "seller456", 50.0, "USD", ListingType::FixedPrice, Some(Utc::now() - Duration::days(1)), // Expired 1 day ago vec!["expired".to_string()], None::, ); // Save the expired listing let (expired_id, db_expired) = db .collection() .expect("can open listing collection") .set(&expired_listing) .expect("can set expired listing"); println!("Expired Listing assigned ID: {}", expired_id); // Check expiration let checked_expired = db_expired.check_expiration(); // Save the checked listing let (_, db_checked_expired) = db .collection() .expect("can open listing collection") .set(&checked_expired) .expect("can set checked listing"); println!("\n1. Listing After Expiration Check:"); print_listing_details(&db_checked_expired); // Demonstrate updating listing details println!("\n--- Updating Listing Details ---"); // Create a new listing to update let listing_to_update = Listing::new( None, // Auto-generated ID "Original Title", "Original description", "asset303", AssetType::Erc20, // Token for a digital asset "seller456", 75.0, "USD", ListingType::FixedPrice, Some(Utc::now() + Duration::days(30)), vec!["original".to_string()], None::, ); // Save the listing let (update_id, db_to_update) = db .collection() .expect("can open listing collection") .set(&listing_to_update) .expect("can set listing to update"); println!("Listing to Update assigned ID: {}", update_id); println!("\n1. Original Listing:"); print_listing_details(&db_to_update); // Update the listing details let updated_listing = db_to_update .update_details( Some("Updated Title"), Some("Updated description with more details"), Some(85.0), Some("https://example.com/images/updated_image.jpg"), ) .add_tags(vec!["updated".to_string(), "premium".to_string()]); // Save the updated listing let (_, db_updated_listing) = db .collection() .expect("can open listing collection") .set(&updated_listing) .expect("can set updated listing"); println!("\n2. Listing After Update:"); print_listing_details(&db_updated_listing); println!("\n--- Model Information ---"); println!("Listing DB Prefix: {}", Listing::db_prefix()); }