bear_lib_terminal/terminal/config/
section.rs

1use std::fmt;
2use std::path::Path;
3use geometry::Size;
4use terminal::config::{ConfigPart, escape_config_string};
5
6
7/// The `terminal` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section repr.
8///
9/// See [`terminal::set()`](../fn.set.html).
10#[derive(Clone, Debug, Eq, PartialEq, Hash)]
11pub struct Terminal {
12	encoding: Option<String>,  //TODO: use an enum/validated struct?
13}
14
15/// The `window` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section repr.
16///
17/// `None` values will not override current ones.
18///
19/// See [`terminal::set()`](../fn.set.html).
20#[derive(Clone, Debug, Eq, PartialEq, Hash)]
21pub struct Window {
22	size: Option<Size>,
23	cellsize: Option<Cellsize>,
24	title: Option<String>,
25	icon: Option<String>,
26	resizeable: Option<bool>,
27	fullscreen: Option<bool>,
28}
29
30/// The `input` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section repr.
31///
32/// `None` values will not override current ones.
33///
34/// See [`terminal::set()`](../fn.set.html).
35#[derive(Clone, Debug, Eq, PartialEq, Hash)]
36pub struct Input {
37	precise_mouse: Option<bool>,
38	mouse_cursor: Option<bool>,
39	cursor_symbol: Option<char>,
40	cursor_blink_rate: Option<i32>,
41}
42
43/// The `output` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section repr.
44///
45/// `None` values will not override current ones.
46///
47/// See [`terminal::set()`](../fn.set.html).
48#[derive(Clone, Debug, Eq, PartialEq, Hash)]
49pub struct Output {
50	postformatting: Option<bool>,
51	vsync: Option<bool>,
52}
53
54
55/// The `log` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section repr.
56///
57/// `None` values will not override current ones.
58///
59/// See [`terminal::set()`](../fn.set.html).
60#[derive(Clone, Debug, Eq, PartialEq, Hash)]
61pub struct Log {
62	file: Option<String>,
63	level: Option<LogLevel>,
64	mode: Option<LogMode>,
65}
66
67
68/// Possible cell size, `Auto` will make the size be selected based on the font.
69#[derive(Clone, Debug, Eq, PartialEq, Hash)]
70pub enum Cellsize {
71	Auto,
72	Sized(Size),
73}
74
75/// Logging levels, as specified [here](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration).
76#[derive(Clone, Debug, Eq, PartialEq, Hash)]
77pub enum LogLevel {
78	None,
79	Fatal,
80	Error,
81	Warning,
82	Info,
83	Debug,
84	Trace,
85}
86
87/// Log writing mode.
88#[derive(Clone, Debug, Eq, PartialEq, Hash)]
89pub enum LogMode {
90	/// Reset the log each time.
91	Truncate,
92	/// Continue writing at the end.
93	Append,
94}
95
96
97impl Terminal {
98	/// Construct a new `terminal` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section override
99	/// segment with a specified used for unibyte strings, which is better left at default, as Rust uses UTF-8 for everything.
100	///
101	/// Default: `"utf8"`.
102	pub fn new(encoding: String) -> Terminal {
103		Terminal{
104			encoding: Some(encoding),
105		}
106	}
107}
108
109impl Window {
110	/// Construct a `window` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section override segment
111	/// with everything being equal to `None`.
112	pub fn empty() -> Window {
113		Window{
114			size: None,
115			cellsize: None,
116			title: None,
117			icon: None,
118			resizeable: None,
119			fullscreen: None,
120		}
121	}
122
123	/// Window size in cells.
124	///
125	/// Default: `80x25`.
126	pub fn size                (mut self, size: Size)         -> Self {self.size       = Some(size)                                       ; self}
127
128	/// Size of all cells, in pixels.
129	///
130	/// Default: [`Cellsize::Auto`](enum.Cellsize.html#variant.Auto).
131	pub fn cellsize            (mut self, cellsize: Cellsize) -> Self {self.cellsize   = Some(cellsize)                                   ; self}
132
133	/// The terminal window's title.
134	///
135	/// Default: `"BearLibTerminal"`.
136	pub fn title               (mut self, title: String)      -> Self {self.title      = Some(title)                                      ; self}
137
138	/// The path of the icon used for the terminal window.
139	///
140	/// Default: none.
141	pub fn icon<T: AsRef<Path>>(mut self, icon: T)            -> Self {self.icon       = Some(icon.as_ref().to_str().unwrap().to_string()); self}
142
143	/// Whether the terminal window should be resizeable.
144	///
145	/// Default: `false`.
146	pub fn resizeable          (mut self, resizeable: bool)   -> Self {self.resizeable = Some(resizeable)                                 ; self}
147
148	/// Whether to enforce fullscreen mode.
149	///
150	/// Default: `false`.
151	pub fn fullscreen          (mut self, fullscreen: bool)   -> Self {self.fullscreen = Some(fullscreen)                                 ; self}
152}
153
154impl Input {
155	/// Construct an `input` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section override segment
156	/// with all elements equal to `None`.
157	pub fn empty() -> Input {
158		Input{
159			precise_mouse: None,
160			mouse_cursor: None,
161			cursor_symbol: None,
162			cursor_blink_rate: None,
163		}
164	}
165
166	/// Whether to generate a mouse-move event when a mouse moves from one pixel to another as opposed to from one cell to another.
167	///
168	/// Default: `false`.
169	pub fn precise_mouse    (mut self, precise_mouse: bool)    -> Self {self.precise_mouse     = Some(precise_mouse)    ; self}
170
171	/// Whether to show the cursor.
172	///
173	/// Default: `true`.
174	pub fn mouse_cursor     (mut self, mouse_cursor: bool)     -> Self {self.mouse_cursor      = Some(mouse_cursor)     ; self}
175
176	/// The cursor symbol to blink in the read string function.
177	///
178	/// Default: `'_'` a.k.a. `0x5F`.
179	pub fn cursor_symbol    (mut self, cursor_symbol: char)    -> Self {self.cursor_symbol     = Some(cursor_symbol)    ; self}
180
181	/// Amount of time in milliseconds to blink the cursor symbol for.
182	///
183	/// Default: `500`.
184	pub fn cursor_blink_rate(mut self, cursor_blink_rate: i32) -> Self {self.cursor_blink_rate = Some(cursor_blink_rate); self}
185}
186
187impl Output {
188	/// Construct an `output` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section override segment
189	/// with all values equalling `None`
190	pub fn clean() -> Output {
191		Output{
192			postformatting: None,
193			vsync: None,
194		}
195	}
196
197	/// Whether to process special tags in the [`print()`](../fn.print.html) function.
198	///
199	/// Default: `true`.
200	pub fn postformatting(mut self, postformatting: bool) -> Self {self.postformatting = Some(postformatting); self}
201
202	/// Toggle OpenGL VSync.
203	///
204	/// Default: `true`.
205	pub fn vsync         (mut self, vsync: bool)          -> Self {self.vsync          = Some(vsync);          self}
206}
207
208impl Log {
209	/// Construct an `log` [configuration](http://foo.wyrd.name/en:bearlibterminal:reference:configuration#library_configuration) section override segment
210	/// with everything set to `None`
211	pub fn empty() -> Log {
212		Log{
213			file: None,
214			level: None,
215			mode: None,
216		}
217	}
218
219	/// The file to write the log to. Note, that, IME, it didn't work.
220	///
221	/// Default: `"bearlibterminal.log"`
222	pub fn file (mut self, file: String)    -> Log {self.file  = Some(file) ; self}
223
224	/// The minimal log level to print at.
225	///
226	/// Default: [`LogLevel::Error`](enum.LogLevel.html#variant.Error)
227	pub fn level(mut self, level: LogLevel) -> Log {self.level = Some(level); self}
228
229	/// How to write to the log file if one laready exists.
230	///
231	/// Default: [`LogMode::Truncate`](enum.LogMode.html#variant.Truncate)
232	pub fn mode (mut self, mode: LogMode)   -> Log {self.mode  = Some(mode) ; self}
233}
234
235
236impl ConfigPart for Terminal {
237	fn to_config_str(&self) -> String {
238		match self.encoding {
239			Some(ref encoding) => format!("terminal.encoding={};", escape_config_string(&encoding)),
240			None               => "".to_string(),
241		}
242	}
243}
244
245impl ConfigPart for Window {
246	fn to_config_str(&self) -> String {
247		if self.size.is_some() || self.cellsize.is_some() || self.title.is_some() || self.icon.is_some() || self.resizeable.is_some() ||
248		   self.fullscreen.is_some() {
249			format!("window: {}, {}, {}, {}, {}, {};",
250				match self.size {
251					Some(ref size) => format!("size={}", size),
252					None           => "".to_string(),
253				},
254				match self.cellsize {
255					Some(ref cellsize) =>
256						match cellsize {
257							&Cellsize::Sized(size) => format!("cellsize={}", size),
258							&Cellsize::Auto        => "cellsize=auto".to_string(),
259						},
260					None               => "".to_string(),
261				},
262				match self.title {
263					Some(ref title) => format!("title={}", escape_config_string(&title)),
264					None            => "".to_string(),
265				},
266				match self.icon {
267					Some(ref icon) => format!("icon={}", escape_config_string(&icon)),
268					None           => "".to_string(),
269				},
270				match self.resizeable {
271					Some(ref resizeable) => format!("resizeable={}", resizeable),
272					None                 => "".to_string(),
273				},
274				match self.fullscreen {
275					Some(ref fullscreen) => format!("fullscreen={}", fullscreen),
276					None                 => "".to_string(),
277				},
278			)
279		} else {
280			"".to_string()
281		}
282	}
283}
284
285impl ConfigPart for Input {
286	fn to_config_str(&self) -> String {
287		if self.precise_mouse.is_some() || self.mouse_cursor.is_some() || self.cursor_symbol.is_some() || self.cursor_blink_rate.is_some() {
288			format!("input: {}, {}, {}, {};",
289				match self.precise_mouse {
290					Some(ref precise_mouse) => format!("precise-mouse={}", precise_mouse),
291					None                    => "".to_string(),
292				},
293				match self.mouse_cursor {
294					Some(ref mouse_cursor) => format!("mouse-cursor={}", mouse_cursor),
295					None                   => "".to_string(),
296				},
297				match self.cursor_symbol {
298					Some(ref cursor_symbol) => format!("cursor-symbol=0x{:x}", *cursor_symbol as i8),
299					None                    => "".to_string(),
300				},
301				match self.cursor_blink_rate {
302					Some(ref cursor_blink_rate) => format!("cursor-blink-rate={}", cursor_blink_rate),
303					None                        => "".to_string(),
304				},
305			)
306		} else {
307			"".to_string()
308		}
309	}
310}
311
312impl ConfigPart for Output {
313	fn to_config_str(&self) -> String {
314		if self.postformatting.is_some() || self.vsync.is_some() {
315			format!("output: {}, {};",
316				match self.postformatting {
317					Some(ref postformatting) => format!("postformatting={}", postformatting),
318					None                     => "".to_string(),
319				},
320				match self.vsync {
321					Some(ref vsync) => format!("vsync={}", vsync),
322					None            => "".to_string(),
323				},
324			)
325		} else {
326			"".to_string()
327		}
328	}
329}
330
331impl ConfigPart for Log {
332	fn to_config_str(&self) -> String {
333		if self.file.is_some() || self.level.is_some() || self.mode.is_some() {
334			format!("log: {}, {}, {};",
335				match self.file {
336					Some(ref file) => format!("file={}", escape_config_string(&file)),
337					None           => "".to_string(),
338				},
339				match self.level {
340					Some(ref level) => format!("level={}", level),
341					None            => "".to_string(),
342				},
343				match self.mode {
344					Some(ref mode) => format!("mode={}", mode),
345					None            => "".to_string(),
346				},
347			)
348		} else {
349			"".to_string()
350		}
351	}
352}
353
354
355impl fmt::Display for LogLevel {
356	fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
357		formatter.write_str(match self {
358			&LogLevel::None    => "none",
359			&LogLevel::Fatal   => "fatal",
360			&LogLevel::Error   => "error",
361			&LogLevel::Warning => "warning",
362			&LogLevel::Info    => "info",
363			&LogLevel::Debug   => "debug",
364			&LogLevel::Trace   => "trace",
365		})
366	}
367}
368
369impl fmt::Display for LogMode {
370	fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
371		formatter.write_str(match self {
372			&LogMode::Truncate => "truncate",
373			&LogMode::Append   => "append",
374		})
375	}
376}