146 lines
3.5 KiB
Rust
146 lines
3.5 KiB
Rust
|
//! Configuration
|
||
|
|
||
|
use std::{fmt::Display, fs::File, io::ErrorKind as IoErrorKind};
|
||
|
|
||
|
use serde::{Deserialize, Serialize};
|
||
|
|
||
|
/// Result alias for this module
|
||
|
pub type Result<T> = std::result::Result<T, Error>;
|
||
|
|
||
|
/// Data for a valid login, including access token and homeserver address
|
||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||
|
pub struct Session {
|
||
|
/// Access token, mxid and device id of the session
|
||
|
pub session: matrix_sdk::Session,
|
||
|
/// The address of the homeserver
|
||
|
pub homeserver: String,
|
||
|
}
|
||
|
|
||
|
impl Session {
|
||
|
/// Read session data from disk.
|
||
|
pub fn from_file() -> Result<Option<Session>> {
|
||
|
let dirs = dirs()?;
|
||
|
let file = File::open(dirs.data_dir().join("session.json"));
|
||
|
let file = match file {
|
||
|
Ok(file) => file,
|
||
|
Err(e) => {
|
||
|
return match e.kind() {
|
||
|
IoErrorKind::NotFound => Ok(None),
|
||
|
_ => Err(e.into()),
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
let session = serde_json::from_reader(file)?;
|
||
|
Ok(session)
|
||
|
}
|
||
|
|
||
|
/// Writes the session data to disk.
|
||
|
pub fn write(&self) -> Result<()> {
|
||
|
let dirs = dirs()?;
|
||
|
std::fs::create_dir_all(dirs.data_dir())?;
|
||
|
let file = File::create(dirs.data_dir().join("session.json"))?;
|
||
|
serde_json::to_writer_pretty(file, self)?;
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Configuration for the application
|
||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||
|
pub struct Config {
|
||
|
/// The global zoom level.
|
||
|
pub zoom: f64,
|
||
|
}
|
||
|
|
||
|
impl Config {
|
||
|
/// Creates a new `Config` with default settings
|
||
|
pub fn new() -> Config {
|
||
|
Config { zoom: 1.0 }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Default for Config {
|
||
|
fn default() -> Self {
|
||
|
Self::new()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Config {
|
||
|
/// Reads the configuration from disk, or creates a new file with default settings if none
|
||
|
/// exists
|
||
|
pub fn from_file() -> Result<Config> {
|
||
|
let dirs = dirs()?;
|
||
|
let file = File::open(dirs.config_dir().join("retrix.json"));
|
||
|
// Create the file if it doesn't exist
|
||
|
let file = match file {
|
||
|
Ok(file) => file,
|
||
|
Err(e) => match e.kind() {
|
||
|
IoErrorKind::NotFound => {
|
||
|
let config = Config::default();
|
||
|
config.write()?;
|
||
|
return Ok(config);
|
||
|
}
|
||
|
_ => return Err(e.into()),
|
||
|
},
|
||
|
};
|
||
|
let config: Config = serde_json::from_reader(file)?;
|
||
|
Ok(config)
|
||
|
}
|
||
|
|
||
|
/// Writes the configuration to disk
|
||
|
pub fn write(&self) -> Result<()> {
|
||
|
let dirs = dirs()?;
|
||
|
std::fs::create_dir_all(dirs.config_dir())?;
|
||
|
let file = File::create(dirs.config_dir().join("retrix.json"))?;
|
||
|
serde_json::to_writer_pretty(file, self)?;
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Generates structure holding paths for config dirs etc.
|
||
|
pub fn dirs() -> Result<dirs::ProjectDirs> {
|
||
|
dirs::ProjectDirs::from("net.amandag", "", "retrix").ok_or(Error::HomeDir)
|
||
|
}
|
||
|
|
||
|
/// Errors which can happen when handling config files
|
||
|
#[derive(Debug)]
|
||
|
pub enum Error {
|
||
|
/// An error happened opening or creating a file
|
||
|
Io(std::io::Error),
|
||
|
/// (De)serializing a file failed
|
||
|
Parsing(serde_json::Error),
|
||
|
/// The home directory couldn't be found
|
||
|
HomeDir,
|
||
|
}
|
||
|
|
||
|
impl Display for Error {
|
||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||
|
match self {
|
||
|
Error::Io(e) => write!(f, "Error opening file: {}", e),
|
||
|
Error::Parsing(e) => write!(f, "Error in config file: {}", e),
|
||
|
Error::HomeDir => write!(f, "Couldn't find home directory"),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl std::error::Error for Error {
|
||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||
|
match *self {
|
||
|
Error::Io(ref e) => Some(e),
|
||
|
Error::Parsing(ref e) => Some(e),
|
||
|
Error::HomeDir => None,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl From<std::io::Error> for Error {
|
||
|
fn from(e: std::io::Error) -> Self {
|
||
|
Error::Io(e)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl From<serde_json::Error> for Error {
|
||
|
fn from(e: serde_json::Error) -> Self {
|
||
|
Error::Parsing(e)
|
||
|
}
|
||
|
}
|