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 #[inline]
90 pub fn dual(&self) -> bool {
91 self.dual
92 }
93
94 pub fn metadata(&self) -> bool {
95 self.metadata
96 }
97
98 pub fn preview(&self) -> bool {
99 self.preview
100 }
101
102 pub fn display_wide_enough(width: u16) -> bool {
104 width >= MIN_WIDTH_FOR_DUAL_PANE
105 }
106
107 pub fn use_dual_tab(&self, width: u16) -> bool {
112 self.dual && Self::display_wide_enough(width)
113 }
114
115 pub fn set_dual(&mut self, dual: bool) {
116 self.dual = dual;
117 self.update_yaml_file();
118 }
119
120 pub fn toggle_dual(&mut self) {
121 self.dual = !self.dual;
122 self.update_yaml_file();
123 }
124
125 pub fn toggle_metadata(&mut self) {
126 self.metadata = !self.metadata;
127 self.update_yaml_file();
128 }
129
130 pub fn set_preview(&mut self) {
131 self.preview = true;
132 self.update_yaml_file();
133 }
134
135 pub fn toggle_preview(&mut self) {
136 self.preview = !self.preview;
137 self.update_yaml_file();
138 }
139
140 fn update_yaml_file(&self) {
143 let mut file = match File::create(&self.filepath) {
144 Ok(file) => file,
145 Err(error) => {
146 log_info!(
147 "Couldn't create session {file}. Error: {error:?}",
148 file = self.filepath
149 );
150 return;
151 }
152 };
153 match to_writer(&mut file, &self) {
154 Ok(()) => (),
155 Err(e) => log_info!(
156 "Couldn't write config to session {file}. Error: {e:?}",
157 file = self.filepath
158 ),
159 }
160 }
161}