dx_forge/api/
cart.rs

1//! Cart System — The Gateway Drug to dx
2
3use anyhow::Result;
4use serde::{Serialize, Deserialize};
5use std::path::PathBuf;
6use parking_lot::RwLock;
7use std::sync::{Arc, OnceLock};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct CartItem {
11    pub id: String,
12    pub package_id: String,
13    pub variant: Option<String>,
14    pub files: Vec<PathBuf>,
15    pub config: serde_json::Value,
16}
17
18static CART: OnceLock<Arc<RwLock<Vec<CartItem>>>> = OnceLock::new();
19
20fn get_cart() -> Arc<RwLock<Vec<CartItem>>> {
21    CART.get_or_init(|| Arc::new(RwLock::new(Vec::new()))).clone()
22}
23
24pub fn stage_item_in_cart(item: CartItem) -> Result<()> {
25    let cart = get_cart();
26    let mut cart = cart.write();
27    
28    tracing::info!("🛒 Staging item in cart: {}", item.package_id);
29    cart.push(item);
30    
31    Ok(())
32}
33
34pub fn commit_entire_cart() -> Result<Vec<PathBuf>> {
35    let cart = get_cart();
36    let cart_items = cart.read().clone();
37    
38    tracing::info!("✅ Committing cart with {} items", cart_items.len());
39    
40    let mut installed_files = Vec::new();
41    
42    for item in &cart_items {
43        // Install each item
44        installed_files.extend(item.files.clone());
45    }
46    
47    // Clear cart after commit
48    drop(cart_items);
49    cart.write().clear();
50    
51    Ok(installed_files)
52}
53
54pub fn commit_cart_immediately() -> Result<Vec<PathBuf>> {
55    commit_entire_cart()
56}
57
58pub fn clear_cart_completely() -> Result<()> {
59    let cart = get_cart();
60    let mut cart = cart.write();
61    
62    tracing::info!("🗑️  Clearing cart ({} items)", cart.len());
63    cart.clear();
64    
65    Ok(())
66}
67
68pub fn remove_specific_cart_item(item_id: &str) -> Result<()> {
69    let cart = get_cart();
70    let mut cart = cart.write();
71    
72    cart.retain(|item| item.id != item_id);
73    tracing::info!("➖ Removed item from cart: {}", item_id);
74    
75    Ok(())
76}
77
78pub fn get_current_cart_contents() -> Result<Vec<CartItem>> {
79    let cart = get_cart();
80    let items = cart.read().clone();
81    Ok(items)
82}
83
84pub fn export_cart_as_shareable_json() -> Result<String> {
85    let cart = get_cart();
86    let cart = cart.read();
87    
88    Ok(serde_json::to_string_pretty(&*cart)?)
89}
90
91pub fn import_cart_from_json(json: &str) -> Result<()> {
92    let items: Vec<CartItem> = serde_json::from_str(json)?;
93    
94    let cart = get_cart();
95    let mut cart = cart.write();
96    
97    tracing::info!("📥 Importing {} items into cart", items.len());
98    cart.extend(items);
99    
100    Ok(())
101}