libnotcurses_sys/notcurses/options/
builder.rs

1//!
2
3use crate::{NcFlag, NcLogLevel, NcOptions};
4use core::ptr::null;
5
6/// Builder object for [`NcOptions`].
7#[derive(Clone, Copy, Debug, Default)]
8pub struct NcOptionsBuilder {
9    // pub(crate): termtype: String,
10    pub(crate) loglevel: NcLogLevel,
11    pub(crate) margin_t: u32,
12    pub(crate) margin_r: u32,
13    pub(crate) margin_b: u32,
14    pub(crate) margin_l: u32,
15    pub(crate) flags: u64,
16}
17
18mod core_impls {
19    use super::{NcOptions, NcOptionsBuilder};
20
21    impl From<NcOptionsBuilder> for NcOptions {
22        fn from(builder: NcOptionsBuilder) -> NcOptions {
23            builder.build()
24        }
25    }
26    impl From<&NcOptionsBuilder> for NcOptions {
27        fn from(builder: &NcOptionsBuilder) -> Self {
28            builder.build()
29        }
30    }
31    impl From<&mut NcOptionsBuilder> for NcOptions {
32        fn from(builder: &mut NcOptionsBuilder) -> Self {
33            builder.build()
34        }
35    }
36    //
37    impl From<NcOptions> for NcOptionsBuilder {
38        fn from(options: NcOptions) -> NcOptionsBuilder {
39            Self::from_options(&options)
40        }
41    }
42    impl From<&NcOptions> for NcOptionsBuilder {
43        fn from(options: &NcOptions) -> Self {
44            Self::from_options(options)
45        }
46    }
47    impl From<&mut NcOptions> for NcOptionsBuilder {
48        fn from(options: &mut NcOptions) -> Self {
49            Self::from_options(options)
50        }
51    }
52}
53
54/// # constructors
55impl NcOptionsBuilder {
56    /// New `NcOptionsBuilder`.
57    pub fn new() -> Self {
58        Self::default()
59    }
60
61    /// New builder from pre-existing options.
62    pub fn from_options(options: &NcOptions) -> Self {
63        let mut builder = Self::default();
64
65        if options.is_drain_input() {
66            builder = builder.drain_input(true);
67        }
68
69        if options.is_inhibit_set_locale() {
70            builder = builder.inhibit_set_locale(true);
71        }
72
73        if options.is_no_alternate_screen() {
74            builder = builder.no_alternate_screen(true);
75        }
76
77        if options.is_no_font_changes() {
78            builder = builder.no_font_changes(true);
79        }
80
81        if options.is_no_quit_sig_handlers() {
82            builder = builder.no_quit_sig_handlers(true);
83        }
84
85        if options.is_no_winch_sig_handler() {
86            builder = builder.no_winch_sig_handler(true);
87        }
88
89        if options.is_preserve_cursor() {
90            builder = builder.preserve_cursor(true);
91        }
92
93        if options.is_scrolling() {
94            builder = builder.scrolling(true);
95        }
96
97        if options.is_cli_mode() {
98            builder = builder.cli_mode(true);
99        }
100
101        if options.is_suppress_banners() {
102            builder = builder.suppress_banners(true);
103        }
104        builder
105    }
106
107    /// Finishes the building and returns [`NcOptions`].
108    pub fn build(self) -> NcOptions {
109        NcOptions {
110            termtype: null(),
111            margin_t: self.margin_t,
112            margin_r: self.margin_r,
113            margin_b: self.margin_b,
114            margin_l: self.margin_l,
115            loglevel: self.loglevel.into(),
116            flags: self.flags,
117        }
118    }
119}
120
121/// # methods (chainable)
122impl NcOptionsBuilder {
123    // /// Sets the TERM type.
124    // pub fn term_type(mut self, term_type: &str) -> Self {
125    //     self.termtype = term_type;
126    //     self
127    // }
128
129    /// Sets the log level.
130    pub fn log_level(mut self, log_level: NcLogLevel) -> Self {
131        self.loglevel = log_level;
132        self
133    }
134
135    /// Sets the margins.
136    pub fn margins(mut self, top: u32, right: u32, bottom: u32, left: u32) -> Self {
137        self.margin_t = top;
138        self.margin_r = right;
139        self.margin_b = bottom;
140        self.margin_l = left;
141        self
142    }
143
144    /// Sets the top margin.
145    pub fn margin_top(mut self, top: u32) -> Self {
146        self.margin_t = top;
147        self
148    }
149
150    /// Sets the right margin.
151    pub fn margin_right(mut self, right: u32) -> Self {
152        self.margin_r = right;
153        self
154    }
155
156    /// Sets the bottom margin.
157    pub fn margin_bottom(mut self, bottom: u32) -> Self {
158        self.margin_b = bottom;
159        self
160    }
161
162    /// Sets the left margin.
163    pub fn margin_left(mut self, left: u32) -> Self {
164        self.margin_l = left;
165        self
166    }
167
168    // flags
169
170    /// If `true`, Input may be freely dropped.
171    ///
172    /// This ought be provided when the program does not intend to handle input.
173    /// Otherwise, input can accumulate in internal buffers, eventually preventing
174    /// Notcurses from processing terminal messages.
175    ///
176    /// See `NcFlag::`[`DrainInput`][NcFlag#associatedconstant.DrainInput].
177    pub fn drain_input(mut self, drain: bool) -> Self {
178        if drain {
179            self.flags |= NcFlag::DrainInput;
180        } else {
181            self.flags &= !NcFlag::DrainInput;
182        }
183        self
184    }
185
186    /// If `true`, wont call setlocale().
187    ///
188    /// See `NcFlag::`[`InhibitSetLocale`][NcFlag#associatedconstant.InhibitSetLocale].
189    pub fn inhibit_set_locale(mut self, inhibit: bool) -> Self {
190        if inhibit {
191            self.flags |= NcFlag::InhibitSetLocale;
192        } else {
193            self.flags &= !NcFlag::InhibitSetLocale;
194        }
195        self
196    }
197
198    /// If `true`, wont enter alternate mode.
199    ///
200    /// See `NcFlag::`[`NoAlternateScreen`][NcFlag#associatedconstant.NoAlternateScreen].
201    pub fn no_alternate_screen(mut self, no_alternate: bool) -> Self {
202        if no_alternate {
203            self.flags |= NcFlag::NoAlternateScreen;
204        } else {
205            self.flags &= !NcFlag::NoAlternateScreen;
206        }
207        self
208    }
209
210    /// If `true`, wont try to clear any preexisting bitmaps.
211    ///
212    /// See `NcFlag::`[`NoClearBitmaps`][NcFlag#associatedconstant.NoClearBitmaps].
213    pub fn no_clear_bitmaps(mut self, no_clear: bool) -> Self {
214        if no_clear {
215            self.flags |= NcFlag::NoClearBitmaps;
216        } else {
217            self.flags &= !NcFlag::NoClearBitmaps;
218        }
219        self
220    }
221
222    /// If `true`, wont modify the font.
223    ///
224    /// See `NcFlag::`[`NoFontChanges`][NcFlag#associatedconstant.NoFontChanges].
225    pub fn no_font_changes(mut self, no_font_changes: bool) -> Self {
226        if no_font_changes {
227            self.flags |= NcFlag::NoFontChanges;
228        } else {
229            self.flags &= !NcFlag::NoFontChanges;
230        }
231        self
232    }
233
234    /// If `true`, wont handle `SIGINT`, `SIGSEGV`, `SIGABRT` nor `SIGQUIT`.
235    ///
236    /// See `NcFlag::`[`NoQuitSigHandlers`][NcFlag#associatedconstant.NoQuitSigHandlers].
237    pub fn no_quit_sig_handlers(mut self, no_quit: bool) -> Self {
238        if no_quit {
239            self.flags |= NcFlag::NoQuitSigHandlers;
240        } else {
241            self.flags &= !NcFlag::NoQuitSigHandlers;
242        }
243        self
244    }
245
246    /// If `true`, wont handle `SIGWINCH`.
247    ///
248    /// See `NcFlag::`[`NoWinchSigHandler`][NcFlag#associatedconstant.NoWinchSigHandler].
249    pub fn no_winch_sig_handler(mut self, no_winch: bool) -> Self {
250        if no_winch {
251            self.flags |= NcFlag::NoWinchSigHandler;
252        } else {
253            self.flags &= !NcFlag::NoWinchSigHandler;
254        }
255        self
256    }
257
258    /// If `true`, will initializes the CLI plane’s virtual cursor to match
259    /// the physical cursor at context creation time.
260    ///
261    /// See `NcFlag::`[`PreserveCursor`][NcFlag#associatedconstant.PreserveCursor].
262    pub fn preserve_cursor(mut self, preserve: bool) -> Self {
263        if preserve {
264            self.flags |= NcFlag::PreserveCursor;
265        } else {
266            self.flags &= !NcFlag::PreserveCursor;
267        }
268        self
269    }
270
271    /// If `true`, will prepare the CLI plane in scrolling mode.
272    ///
273    /// See `NcFlag::`[`Scrolling`][NcFlag#associatedconstant.Scrolling].
274    pub fn scrolling(mut self, scrolling: bool) -> Self {
275        if scrolling {
276            self.flags |= NcFlag::Scrolling;
277        } else {
278            self.flags &= !NcFlag::Scrolling;
279        }
280        self
281    }
282
283    /// A shortcut for setting the following options together:
284    /// `no_alternate_screen`, `no_clear_bitmaps`, `preserve_cursor` & `scrolling`.
285    ///
286    /// See `NcFlag::`[`CliMode`][NcFlag#associatedconstant.CliMode].
287    pub fn cli_mode(mut self, cli_mode: bool) -> Self {
288        if cli_mode {
289            self.flags |= NcFlag::CliMode;
290        } else {
291            self.flags &= !NcFlag::CliMode;
292        }
293        self
294    }
295
296    /// If `true`, wont print banners.
297    ///
298    /// See `NcFlag::`[`SuppressBanners`][NcFlag#associatedconstant.SuppressBanners].
299    pub fn suppress_banners(mut self, suppress_banners: bool) -> Self {
300        if suppress_banners {
301            self.flags |= NcFlag::SuppressBanners;
302        } else {
303            self.flags &= !NcFlag::SuppressBanners;
304        }
305        self
306    }
307}
308
309/// # methods (settable)
310impl NcOptionsBuilder {
311    // /// Sets the TERM type.
312    // pub fn set_term_type(&mut self, term_type: &str) {
313    //     self.termtype = term_type;
314    // }
315
316    /// Sets the log level.
317    pub fn set_log_level(&mut self, log_level: NcLogLevel) {
318        self.loglevel = log_level;
319    }
320
321    /// Sets the margins.
322    pub fn set_margins(&mut self, top: u32, right: u32, bottom: u32, left: u32) {
323        self.margin_t = top;
324        self.margin_r = right;
325        self.margin_b = bottom;
326        self.margin_l = left;
327    }
328
329    /// Sets the top margin.
330    pub fn set_margin_top(&mut self, top: u32) {
331        self.margin_t = top;
332    }
333
334    /// Sets the right margin.
335    pub fn set_margin_right(&mut self, right: u32) {
336        self.margin_r = right;
337    }
338
339    /// Sets the bottom margin.
340    pub fn set_margin_bottom(&mut self, bottom: u32) {
341        self.margin_b = bottom;
342    }
343
344    /// Sets the left margin.
345    pub fn set_margin_left(&mut self, left: u32) {
346        self.margin_l = left;
347    }
348
349    // flags
350
351    /// If `true`, Input may be freely dropped.
352    ///
353    /// This ought be provided when the program does not intend to handle input.
354    /// Otherwise, input can accumulate in internal buffers, eventually preventing
355    /// Notcurses from processing terminal messages.
356    ///
357    /// See `NcFlag::`[`DrainInput`][NcFlag#associatedconstant.DrainInput].
358    pub fn set_drain_input(&mut self, drain: bool) {
359        if drain {
360            self.flags |= NcFlag::DrainInput;
361        } else {
362            self.flags &= !NcFlag::DrainInput;
363        }
364    }
365
366    /// If `true`, wont call setlocale().
367    ///
368    /// See `NcFlag::`[`InhibitSetLocale`][NcFlag#associatedconstant.InhibitSetLocale].
369    pub fn set_inhibit_set_locale(&mut self, inhibit: bool) {
370        if inhibit {
371            self.flags |= NcFlag::InhibitSetLocale;
372        } else {
373            self.flags &= !NcFlag::InhibitSetLocale;
374        }
375    }
376
377    /// If `true`, wont enter alternate mode.
378    ///
379    /// See `NcFlag::`[`NoAlternateScreen`][NcFlag#associatedconstant.NoAlternateScreen].
380    pub fn set_no_alternate_screen(&mut self, no_alternate: bool) {
381        if no_alternate {
382            self.flags |= NcFlag::NoAlternateScreen;
383        } else {
384            self.flags &= !NcFlag::NoAlternateScreen;
385        }
386    }
387
388    /// If `true`, wont try to clear any preexisting bitmaps.
389    ///
390    /// See `NcFlag::`[`NoClearBitmaps`][NcFlag#associatedconstant.NoClearBitmaps].
391    pub fn set_no_clear_bitmaps(&mut self, no_clear: bool) {
392        if no_clear {
393            self.flags |= NcFlag::NoClearBitmaps;
394        } else {
395            self.flags &= !NcFlag::NoClearBitmaps;
396        }
397    }
398
399    /// If `true`, wont modify the font.
400    ///
401    /// See `NcFlag::`[`NoFontChanges`][NcFlag#associatedconstant.NoFontChanges].
402    pub fn set_no_font_changes(&mut self, no_font_changes: bool) {
403        if no_font_changes {
404            self.flags |= NcFlag::NoFontChanges;
405        } else {
406            self.flags &= !NcFlag::NoFontChanges;
407        }
408    }
409
410    /// If `true`, wont handle `SIGINT`, `SIGSEGV`, `SIGABRT` nor `SIGQUIT`.
411    ///
412    /// See `NcFlag::`[`NoQuitSigHandlers`][NcFlag#associatedconstant.NoQuitSigHandlers].
413    pub fn set_no_quit_sig_handlers(&mut self, no_quit: bool) {
414        if no_quit {
415            self.flags |= NcFlag::NoQuitSigHandlers;
416        } else {
417            self.flags &= !NcFlag::NoQuitSigHandlers;
418        }
419    }
420
421    /// If `true`, wont handle `SIGWINCH`.
422    ///
423    /// See `NcFlag::`[`NoWinchSigHandler`][NcFlag#associatedconstant.NoWinchSigHandler].
424    pub fn set_no_winch_sig_handler(&mut self, no_winch: bool) {
425        if no_winch {
426            self.flags |= NcFlag::NoWinchSigHandler;
427        } else {
428            self.flags &= !NcFlag::NoWinchSigHandler;
429        }
430    }
431
432    /// If `true`, will initializes the CLI plane’s virtual cursor to match
433    /// the physical cursor at context creation time.
434    ///
435    /// See `NcFlag::`[`PreserveCursor`][NcFlag#associatedconstant.PreserveCursor].
436    pub fn set_preserve_cursor(&mut self, preserve: bool) {
437        if preserve {
438            self.flags |= NcFlag::PreserveCursor;
439        } else {
440            self.flags &= !NcFlag::PreserveCursor;
441        }
442    }
443
444    /// If `true`, will prepare the CLI plane in scrolling mode.
445    ///
446    /// See `NcFlag::`[`Scrolling`][NcFlag#associatedconstant.Scrolling].
447    pub fn set_scrolling(&mut self, scrolling: bool) {
448        if scrolling {
449            self.flags |= NcFlag::Scrolling;
450        } else {
451            self.flags &= !NcFlag::Scrolling;
452        }
453    }
454
455    /// A shortcut for setting the following options together:
456    /// `no_alternate_screen`, `no_clear_bitmaps`, `preserve_cursor` & `scrolling`.
457    ///
458    /// See `NcFlag::`[`CliMode`][NcFlag#associatedconstant.CliMode].
459    pub fn set_cli_mode(&mut self, cli_mode: bool) {
460        if cli_mode {
461            self.flags |= NcFlag::CliMode;
462        } else {
463            self.flags &= !NcFlag::CliMode;
464        }
465    }
466
467    /// If `true`, wont print banners.
468    ///
469    /// See `NcFlag::`[`SuppressBanners`][NcFlag#associatedconstant.SuppressBanners].
470    pub fn set_suppress_banners(&mut self, suppress_banners: bool) {
471        if suppress_banners {
472            self.flags |= NcFlag::SuppressBanners;
473        } else {
474            self.flags &= !NcFlag::SuppressBanners;
475        }
476    }
477}
478
479/// # query methods
480impl NcOptionsBuilder {
481    /// Returns the `(top, right, bottom, left)` margins.
482    pub fn get_margins(&self) -> (u32, u32, u32, u32) {
483        (self.margin_t, self.margin_r, self.margin_b, self.margin_l)
484    }
485
486    /// Returns the log level.
487    pub fn get_log_level(&self) -> NcLogLevel {
488        self.loglevel
489    }
490
491    //
492
493    /// Returns `true` if it has the [`DrainInput`] flag set.
494    ///
495    /// [`DrainInput`]: NcFlag#associatedconstant.DrainInput
496    pub fn is_drain_input(&self) -> bool {
497        self.flags & NcFlag::DrainInput != NcFlag::None
498    }
499
500    /// Returns `true` if it has the [`InhibitSetLocale`] flag set.
501    ///
502    /// [`InhibitSetLocale`]: NcFlag#associatedconstant.InhibitSetLocale
503    pub fn is_inhibit_set_locale(&self) -> bool {
504        self.flags & NcFlag::InhibitSetLocale != NcFlag::None
505    }
506
507    /// Returns `true` if it has the [`NoAlternateScreen`] flag set.
508    ///
509    /// [`NoAlternateScreen`]: NcFlag#associatedconstant.NoAlternateScreen
510    pub fn is_no_alternate_screen(&self) -> bool {
511        self.flags & NcFlag::NoAlternateScreen != NcFlag::None
512    }
513
514    /// Returns `true` if it has the [`NoClearBitmaps`] flag set.
515    ///
516    /// [`NoClearBitmaps`]: NcFlag#associatedconstant.NoClearBitmaps
517    pub fn is_no_clear_bitmaps(&self) -> bool {
518        self.flags & NcFlag::NoClearBitmaps != NcFlag::None
519    }
520
521    /// Returns `true` if it has the [`NoFontChanges`] flag set.
522    ///
523    /// [`NoFontChanges`]: NcFlag#associatedconstant.NoFontChanges
524    pub fn is_no_font_changes(&self) -> bool {
525        self.flags & NcFlag::NoFontChanges != NcFlag::None
526    }
527
528    /// Returns `true` if it has the [`NoQuitSigHandlers`] flag set.
529    ///
530    /// [`NoQuitSigHandlers`]: NcFlag#associatedconstant.NoQuitSigHandlers
531    pub fn is_no_quit_sig_handlers(&self) -> bool {
532        self.flags & NcFlag::NoQuitSigHandlers != NcFlag::None
533    }
534
535    /// Returns `true` if it has the [`NoWinchSigHandler`] flag set.
536    ///
537    /// [`NoWinchSigHandler`]: NcFlag#associatedconstant.NoWinchSigHandler
538    pub fn is_no_winch_sig_handler(&self) -> bool {
539        self.flags & NcFlag::NoWinchSigHandler != NcFlag::None
540    }
541
542    /// Returns `true` if it has the [`PreserveCursor`] flag set.
543    ///
544    /// [`PreserveCursor`]: NcFlag#associatedconstant.PreserveCursor
545    pub fn is_preserve_cursor(&self) -> bool {
546        self.flags & NcFlag::PreserveCursor != NcFlag::None
547    }
548
549    /// Returns `true` if it has the [`Scrolling`] flag set.
550    ///
551    /// [`Scrolling`]: NcFlag#associatedconstant.Scrolling
552    pub fn is_scrolling(&self) -> bool {
553        self.flags & NcFlag::Scrolling != NcFlag::None
554    }
555
556    /// Returns `true` if it has the [`CliMode`] flag set.
557    ///
558    /// [`CliMode`]: NcFlag#associatedconstant.CliMode
559    pub fn is_cli_mode(&self) -> bool {
560        self.flags & NcFlag::CliMode != NcFlag::None
561    }
562
563    /// Returns `true` if it has the [`SuppressBanners`] flag set.
564    ///
565    /// [`SuppressBanners`]: NcFlag#associatedconstant.SuppressBanners
566    pub fn is_suppress_banners(&self) -> bool {
567        self.flags & NcFlag::SuppressBanners != NcFlag::None
568    }
569}