use std::fs::File;
use serde::Serialize;
use serde_yaml_ng::{from_reader, to_writer, Error as YamlError, Value as YamlValue};
use crate::common::{tilde, SESSION_PATH};
use crate::io::MIN_WIDTH_FOR_DUAL_PANE;
use crate::log_info;
#[derive(Debug, Serialize)]
pub struct Session {
dual: bool,
metadata: bool,
preview: bool,
#[serde(skip_serializing)]
filepath: String,
}
impl Default for Session {
fn default() -> Self {
Self {
dual: true,
metadata: true,
preview: false,
filepath: tilde(SESSION_PATH).to_string(),
}
}
}
impl Session {
pub fn new(width: u16) -> Self {
Self::default().update_from_config(width)
}
fn update_from_config(mut self, width: u16) -> Self {
let Ok(file) = File::open(&self.filepath) else {
log_info!("Couldn't open file {file}", file = self.filepath);
return self;
};
let Ok(yaml): Result<YamlValue, YamlError> = from_reader(file) else {
log_info!(
"Couldn't parse session from file {file}",
file = self.filepath
);
return self;
};
match yaml["dual"] {
YamlValue::Bool(value) => self.dual = Self::parse_dual_pane(value, width),
_ => self.dual = true,
}
match yaml["metadata"] {
YamlValue::Bool(value) => self.metadata = value,
_ => self.metadata = true,
}
match yaml["preview"] {
YamlValue::Bool(value) => self.preview = value,
_ => self.preview = false,
}
self
}
fn parse_dual_pane(session_bool: bool, width: u16) -> bool {
if !Self::display_wide_enough(width) {
return false;
}
session_bool
}
pub fn dual(&self) -> bool {
self.dual
}
pub fn metadata(&self) -> bool {
self.metadata
}
pub fn preview(&self) -> bool {
self.preview
}
pub fn display_wide_enough(width: u16) -> bool {
width >= MIN_WIDTH_FOR_DUAL_PANE
}
pub fn use_dual_tab(&self, width: u16) -> bool {
self.dual && Self::display_wide_enough(width)
}
pub fn set_dual(&mut self, dual: bool) {
self.dual = dual;
self.update_yaml_file();
}
pub fn toggle_dual(&mut self) {
self.dual = !self.dual;
self.update_yaml_file();
}
pub fn toggle_metadata(&mut self) {
self.metadata = !self.metadata;
self.update_yaml_file();
}
pub fn set_preview(&mut self) {
self.preview = true;
self.update_yaml_file();
}
pub fn toggle_preview(&mut self) {
self.preview = !self.preview;
self.update_yaml_file();
}
fn update_yaml_file(&self) {
let mut file = match File::create(&self.filepath) {
Ok(file) => file,
Err(error) => {
log_info!(
"Couldn't create session {file}. Error: {error:?}",
file = self.filepath
);
return;
}
};
match to_writer(&mut file, &self) {
Ok(()) => (),
Err(e) => log_info!(
"Couldn't write config to session {file}. Error: {e:?}",
file = self.filepath
),
}
}
}