use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionConfig {
pub api_base: String,
pub session_token: String,
#[serde(default)]
pub last_character_id: Option<Uuid>,
}
impl SessionConfig {
pub fn path() -> anyhow::Result<PathBuf> {
let base = dirs::config_dir()
.ok_or_else(|| anyhow::anyhow!("could not resolve config directory"))?;
Ok(base.join("flatland").join("session.json"))
}
pub fn load() -> anyhow::Result<Self> {
let path = Self::path()?;
let bytes = std::fs::read(&path)
.map_err(|_| anyhow::anyhow!("not logged in; run `flatland3 auth login`"))?;
Ok(serde_json::from_slice(&bytes)?)
}
pub fn save(&self) -> anyhow::Result<()> {
let path = Self::path()?;
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(path, serde_json::to_vec_pretty(self)?)?;
Ok(())
}
pub fn remember_character(&mut self, character_id: Uuid) -> anyhow::Result<()> {
if self.last_character_id == Some(character_id) {
return Ok(());
}
self.last_character_id = Some(character_id);
self.save()
}
#[allow(dead_code)] pub fn clear() -> anyhow::Result<()> {
let path = Self::path()?;
match std::fs::remove_file(&path) {
Ok(()) => Ok(()),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(err) => Err(err.into()),
}
}
#[allow(dead_code)] pub fn exists() -> bool {
Self::path().ok().map(|p| p.is_file()).unwrap_or(false)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SavedLogin {
pub email: String,
pub password: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub api_base: Option<String>,
}
impl SavedLogin {
pub fn path() -> anyhow::Result<PathBuf> {
let base = dirs::config_dir()
.ok_or_else(|| anyhow::anyhow!("could not resolve config directory"))?;
Ok(base.join("flatland").join("login.json"))
}
#[allow(dead_code)] pub fn load() -> Option<Self> {
let path = Self::path().ok()?;
let bytes = std::fs::read(path).ok()?;
serde_json::from_slice(&bytes).ok()
}
#[allow(dead_code)] pub fn save(&self) -> anyhow::Result<()> {
let path = Self::path()?;
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(&path, serde_json::to_vec_pretty(self)?)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let _ = std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600));
}
Ok(())
}
#[allow(dead_code)]
pub fn clear() -> anyhow::Result<()> {
let path = Self::path()?;
match std::fs::remove_file(&path) {
Ok(()) => Ok(()),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(err) => Err(err.into()),
}
}
}
pub fn default_api_base() -> String {
flatland_client_lib::default_api_base_url()
}