steam-user 0.1.0

Steam User web client for Rust - HTTP-based Steam Community interactions
Documentation
//! Trade-related types.

use serde::{Deserialize, Serialize};
use steamid::SteamID;

/// A Steam trade offer.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeOffer {
    /// Unique identifier for the trade offer.
    pub tradeofferid: u64,
    /// Trading partner information.
    pub partner: TradeOfferPartner,
    /// Whether the trade offer is currently active.
    pub active: bool,
    /// Items from the primary perspective (usually the current user).
    pub primary: TradeOfferItems,
    /// Items from the secondary perspective (the partner).
    pub secondary: TradeOfferItems,
    /// Status banner text (e.g., "Items Now Unavailable For Trade", "Trade
    /// Accepted 8 Mar, 2026 @ 3:46am").
    #[serde(default)]
    pub banner_text: String,
    /// Unix timestamp parsed from banner_text (if it contains a date), in UTC
    /// seconds.
    #[serde(default)]
    pub banner_timestamp: Option<i64>,
    /// Status derived from banner (e.g., "accepted", "unavailable", "active").
    #[serde(default)]
    pub status: TradeOfferStatus,
}

/// Status of a trade offer, derived from the HTML banner class and text.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum TradeOfferStatus {
    /// Trade is active and can be accepted/declined.
    #[default]
    Active,
    /// Trade was accepted.
    Accepted,
    /// Trade expired or items are no longer available.
    Unavailable,
    /// Trade was countered.
    Countered,
    /// Other/unknown inactive state.
    Inactive,
}

/// Trading partner details in a trade offer.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeOfferPartner {
    /// Partner's SteamID. `None` if the offer HTML did not expose a parseable
    /// SteamID (rare — Steam embeds it in `ReportTradeScam(steamid, ...)`).
    #[serde(default)]
    pub steamid: Option<SteamID>,
    /// Display name.
    pub name: String,
    /// Avatar hash.
    pub avatar_hash: String,
    /// Profile link.
    pub link: String,
    /// Header text (e.g., "You have a trade offer from...").
    pub header: String,
}

/// Container for assets belonging to one side of a trade.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeOfferItems {
    /// SteamID of the owner of these items. `None` if the `data-miniprofile`
    /// attribute was missing or unparseable.
    #[serde(default)]
    pub steamid: Option<SteamID>,
    /// List of items in this side of the trade.
    pub items: Vec<TradeOfferItem>,
}

/// A single item within a trade offer summary.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeOfferItem {
    /// Economy item string (e.g., "classinfo/730/310777338/302028390").
    pub economy_item: String,
    /// Image URL (standard resolution).
    pub img: String,
    /// High-resolution image URL (2x), if available from srcset.
    #[serde(default)]
    pub img_hi: String,
    /// Whether this item is marked as missing/unavailable in the trade.
    #[serde(default)]
    pub missing: bool,
}

/// Response containing trade offers summary and active offers.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeOffersResponse {
    /// Summary of incoming offers.
    pub incoming_offers: TradeOfferSummary,
    /// Summary of sent offers.
    pub sent_offers: TradeOfferSummary,
    /// Number of trades on hold.
    pub trade_hold_count: u32,
    /// List of parsed trade offer details.
    pub trade_offers: Vec<TradeOffer>,
}

/// Summary information for a category of trade offers.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeOfferSummary {
    /// URL to view these offers.
    pub link: String,
    /// Count of offers in this category.
    pub count: u32,
}

/// An asset being offered or requested in a new trade offer.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeOfferAsset {
    /// App ID of the item.
    pub appid: u32,
    /// Context ID of the item.
    pub contextid: String,
    /// Amount (usually 1).
    pub amount: u32,
    /// Asset ID.
    pub assetid: String,
}

/// Result of sending a trade offer.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeOfferResult {
    /// The ID of the created trade offer.
    pub tradeofferid: String,
    /// Whether mobile confirmation is required.
    pub needs_mobile_confirmation: bool,
    /// Whether email confirmation is required.
    pub needs_email_confirmation: bool,
    /// Domain of the confirmation email, if applicable.
    pub email_domain: Option<String>,
}

/// Information extracted from a trade offer URL.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ParsedTradeURL {
    /// Account ID (32-bit).
    pub account_id: String,
    /// SteamID (64-bit).
    pub steam_id: SteamID,
    /// Trade access token.
    pub token: Option<String>,
}

/// Cursor for paginating inventory history.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InventoryCursor {
    pub time: u64,
    pub time_frac: u32,
    pub s: u32,
}

impl Default for InventoryCursor {
    fn default() -> Self {
        use std::time::{SystemTime, UNIX_EPOCH};
        let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();

        Self { time: now, time_frac: 0, s: 0 }
    }
}

/// A row in the inventory history.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InventoryHistoryItem {
    pub id: String,
    pub timestamp: u64,
    pub timestamp_str: String,
    pub description: String,
    pub plusminus: String,
    pub trade_history_items: Vec<serde_json::Value>,
    /// SteamID of the account whose history this row belongs to (i.e. the
    /// logged-in user). `None` only if there is no active session.
    #[serde(default)]
    pub steamid: Option<SteamID>,
    pub trade_people: Option<TradePeople>,
}

/// Trading partner in inventory history.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradePeople {
    pub name: String,
    pub url: String,
}

/// Result of fetching inventory history.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InventoryHistoryResult {
    pub cursor: Option<InventoryCursor>,
    pub trade_history: Vec<InventoryHistoryItem>,
}