steam-client-rs 0.1.0

Steam client for Rust - Individual and Anonymous user account types
Documentation
use std::{collections::HashMap, fs, path::PathBuf};

use serde::{Deserialize, Serialize};

use crate::LogOnDetails;

#[derive(Serialize, Deserialize, Debug, Clone)]
struct SavedSession {
    account_name: String,
    refresh_token: String,
    steam_id: u64,
}

pub struct TokenStore {
    path: PathBuf,
}

impl TokenStore {
    pub fn new(filename: &str) -> Self {
        Self { path: PathBuf::from(filename) }
    }

    /// Load all sessions from disk
    fn load_all(&self) -> HashMap<String, SavedSession> {
        if !self.path.exists() {
            return HashMap::new();
        }
        let data = match fs::read_to_string(&self.path) {
            Ok(d) => d,
            Err(_) => return HashMap::new(),
        };
        serde_json::from_str(&data).unwrap_or_default()
    }

    /// Attempt to load a session for a specific user.
    /// If no user specified, returns the first one found (single-user mode).
    pub fn load(&self, account_name: Option<&str>) -> Option<LogOnDetails> {
        let sessions = self.load_all();

        let session = if let Some(name) = account_name {
            sessions.get(name)?
        } else {
            // "Default" behavior: just grab the first one
            sessions.values().next()?
        };

        Some(LogOnDetails {
            account_name: Some(session.account_name.clone()),
            refresh_token: Some(session.refresh_token.clone()),
            // steam_id: Some(session.steam_id), // Useful for pre-filling
            ..Default::default()
        })
    }

    /// Save a token (updates existing entry or adds new one)
    pub fn save(&self, account_name: String, token: String, steam_id: u64) -> std::io::Result<()> {
        let mut sessions = self.load_all();

        sessions.insert(account_name.clone(), SavedSession { account_name: account_name.clone(), refresh_token: token, steam_id });

        let data = serde_json::to_string_pretty(&sessions)?;
        fs::write(&self.path, data)
    }
}