1use std::fs::File;
2
3use serde::Serialize;
4use serde_yaml_ng::{from_reader, to_writer, Error as YamlError, Value as YamlValue};
5
6use crate::common::{tilde, SESSION_PATH};
7use crate::io::MIN_WIDTH_FOR_DUAL_PANE;
8use crate::log_info;
9
10#[derive(Debug, Serialize)]
24pub struct Session {
25 dual: bool,
27 metadata: bool,
29 preview: bool,
31 #[serde(skip_serializing)]
33 filepath: String,
34}
35
36impl Default for Session {
37 fn default() -> Self {
38 Self {
39 dual: true,
40 metadata: true,
41 preview: false,
42 filepath: tilde(SESSION_PATH).to_string(),
43 }
44 }
45}
46
47impl Session {
48 pub fn new(width: u16) -> Self {
52 Self::default().update_from_config(width)
53 }
54
55 fn update_from_config(mut self, width: u16) -> Self {
56 let Ok(file) = File::open(&self.filepath) else {
57 log_info!("Couldn't open file {file}", file = self.filepath);
58 return self;
59 };
60 let Ok(yaml): Result<YamlValue, YamlError> = from_reader(file) else {
61 log_info!(
62 "Couldn't parse session from file {file}",
63 file = self.filepath
64 );
65 return self;
66 };
67 match yaml["dual"] {
68 YamlValue::Bool(value) => self.dual = Self::parse_dual_pane(value, width),
69 _ => self.dual = true,
70 }
71 match yaml["metadata"] {
72 YamlValue::Bool(value) => self.metadata = value,
73 _ => self.metadata = true,
74 }
75 match yaml["preview"] {
76 YamlValue::Bool(value) => self.preview = value,
77 _ => self.preview = false,
78 }
79 self
80 }
81
82 fn parse_dual_pane(session_bool: bool, width: u16) -> bool {
83 if !Self::display_wide_enough(width) {
84 return false;
85 }
86 session_bool
87 }
88
89 pub fn dual(&self) -> bool {
90 self.dual
91 }
92
93 pub fn metadata(&self) -> bool {
94 self.metadata
95 }
96
97 pub fn preview(&self) -> bool {
98 self.preview
99 }
100
101 pub fn display_wide_enough(width: u16) -> bool {
103 width >= MIN_WIDTH_FOR_DUAL_PANE
104 }
105
106 pub fn use_dual_tab(&self, width: u16) -> bool {
111 self.dual && Self::display_wide_enough(width)
112 }
113
114 pub fn set_dual(&mut self, dual: bool) {
115 self.dual = dual;
116 self.update_yaml_file();
117 }
118
119 pub fn toggle_dual(&mut self) {
120 self.dual = !self.dual;
121 self.update_yaml_file();
122 }
123
124 pub fn toggle_metadata(&mut self) {
125 self.metadata = !self.metadata;
126 self.update_yaml_file();
127 }
128
129 pub fn set_preview(&mut self) {
130 self.preview = true;
131 self.update_yaml_file();
132 }
133
134 pub fn toggle_preview(&mut self) {
135 self.preview = !self.preview;
136 self.update_yaml_file();
137 }
138
139 fn update_yaml_file(&self) {
142 let mut file = match File::create(&self.filepath) {
143 Ok(file) => file,
144 Err(error) => {
145 log_info!(
146 "Couldn't create session {file}. Error: {error:?}",
147 file = self.filepath
148 );
149 return;
150 }
151 };
152 match to_writer(&mut file, &self) {
153 Ok(()) => (),
154 Err(e) => log_info!(
155 "Couldn't write config to session {file}. Error: {e:?}",
156 file = self.filepath
157 ),
158 }
159 }
160}