1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
//! `NcDirect`

// total: 63
// ---------------------------------------------------
// (X)  1 : wont do
// (~)  3 : TODO / WIP
//
// (f) 46 : unsafe ffi function exported by bindgen
// (w)  1 : safely wrapped ffi function
// (r) 11 : static function manually reimplemented
//
// (m) 54 : method implemented
//
// (t)  0 : unit test done for the function
// (T)  0 : unit test done also for the method
// ---------------------------------------------------
// fm  ncdirect_bg_default
// fm  ncdirect_bg_palindex
// fm  ncdirect_bg_rgb
// fm  ncdirect_box
// rm  ncdirect_canbraille
// rm  ncdirect_canchangecolor
// fm  ncdirect_canget_cursor
// rm  ncdirect_canfade
// rm  ncdirect_canhalfblock
// rm  ncdirect_canopen_images
// rm  ncdirect_canopen_videos
// rm  ncdirect_canquadrant
// rm  ncdirect_cantruecolor
// fm  ncdirect_canutf8
// wm  ncdirect_capabilities
// fm  ncdirect_check_pixel_support
// fm  ncdirect_clear
//~f   ncdirect_core_init
// fm  ncdirect_cursor_disable
// fm  ncdirect_cursor_down
// fm  ncdirect_cursor_enable
// fm  ncdirect_cursor_left
// fm  ncdirect_cursor_move_yx
// fm  ncdirect_cursor_pop
// fm  ncdirect_cursor_push
// fm  ncdirect_cursor_right
// fm  ncdirect_cursor_up
// fm  ncdirect_cursor_yx
// fm  ncdirect_detected_terminal
// fm  ncdirect_dim_x
// fm  ncdirect_dim_y
// fm  ncdirect_double_box
// fm  ncdirect_fg_default
// fm  ncdirect_fg_palindex
// fm  ncdirect_fg_rgb
// fm  ncdirect_flush
// fm  ncdirect_get
//~r   ncdirect_heavy_box,
// fm  ncdirect_hline_interp
// fm  ncdirect_init
// fm  ncdirect_inputready_fd
//~r   ncdirect_light_box,
// fm  ncplane_on_styles
// fm  ncplane_off_styles
// fm  ncdirect_palette_size
//X    ncdirect_printf_aligned
// f   ncdirect_putegc
// fm  ncdirect_putstr
// fm  ncdirect_raster_frame
// fm  ncdirect_readline
// fm  ncdirect_render_frame
// fm  ncdirect_render_image
// fm  ncdirect_rounded_box
// fm  ncdirect_set_styles
// fm  ncdirect_stop
// f   ncdirect_stream
// f   ncdirect_styles
// f   ncdirect_supported_styles
// fm  ncdirect_vline_interp
// r   ncdirect_bg_rgb8           // unneeded method
// r   ncdirect_fg_rgb8           // unneeded method
// rm  ncdirect_get_blocking
// rm  ncdirect_get_nblock

#[cfg(test)]
mod test;

mod methods;
pub(crate) mod reimplemented;

use c_api::NcDirectFlag_u64;

/// Minimal notcurses instance for styling text.
pub type NcDirect = crate::c_api::ffi::ncdirect;

/// A bitmask of [`NcDirect`][crate::NcDirect] flags.
///
/// # Flag
/// - [`DrainInput`][NcDirectFlag::DrainInput]
/// - [`InhibitCbreak`][NcDirectFlag::InhibitCbreak]
/// - [`InhibitSetLocale`][NcDirectFlag::InhibitSetLocale]
/// - [`NoQuitSigHandlers`][NcDirectFlag::NoQuitSigHandlers]
/// - [`Verbose`][NcDirectFlag::Verbose]
/// - [`VeryVerbose`][NcDirectFlag::VeryVerbose]
///
/// # Default
/// *[`NcDirectFlag::None`]
///
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct NcDirectFlag(pub NcDirectFlag_u64);

///
impl NcDirectFlag {
    /// No flags.
    pub const None: NcDirectFlag = Self(0);

    /// Flag that indicates input may be freely dropped.
    ///
    /// This ought be provided when the program does not intend to handle input.
    /// Otherwise, input can accumulate in internal buffers, eventually preventing
    /// Notcurses from processing terminal messages.
    pub const DrainInput: NcDirectFlag =
        Self(c_api::NCDIRECT_OPTION_DRAIN_INPUT as NcDirectFlag_u64);

    /// Flag that avoids placing the terminal into cbreak mode
    /// (disabling echo and line buffering).
    ///
    pub const InhibitCbreak: NcDirectFlag =
        Self(c_api::NCDIRECT_OPTION_INHIBIT_CBREAK as NcDirectFlag_u64);

    /// Flag that avoids calling setlocale(LC_ALL, NULL).
    ///
    /// If the result is either "C" or "POSIX", it will print a
    /// diagnostic to stderr, and then call setlocale(LC_ALL, "").
    ///
    /// This will attempt to set the locale based off the LANG
    /// environment variable. Your program should call setlocale(3)
    /// itself, usually as one of the first lines.
    ///
    pub const InhibitSetLocale: NcDirectFlag =
        Self(c_api::NCDIRECT_OPTION_INHIBIT_SETLOCALE as NcDirectFlag_u64);

    /// Flag that inhibits registration of the `SIGABRT`, `SIGBUS`, `SIGFPE`,
    /// `SIGILL`, `SIGINT`, `SIGQUIT`, `SIGSEGV` and `SIGTERM`, signal handlers.
    pub const NoQuitSigHandlers: NcDirectFlag =
        Self(c_api::NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS as NcDirectFlag_u64);

    /// Flag that enables showing detailed information.
    pub const Verbose: NcDirectFlag = Self(c_api::NCDIRECT_OPTION_VERBOSE as NcDirectFlag_u64);

    /// Flag that enables showing all diagnostics (equivalent to
    /// [`NcLogLevel::trace`]. Implies [`NcDirectFlag::Verbose`].
    ///
    /// [`NcLogLevel::Trace`]: crate::NcLogLevel#associatedconstant.Trace
    pub const VeryVerbose: NcDirectFlag =
        Self(c_api::NCDIRECT_OPTION_VERY_VERBOSE as NcDirectFlag_u64);
}

mod std_impls {
    use super::{c_api::NcDirectFlag_u64, NcDirectFlag};

    impl Default for NcDirectFlag {
        fn default() -> Self {
            Self::None
        }
    }

    crate::from_primitive![NcDirectFlag, NcDirectFlag_u64];
    crate::unit_impl_from![NcDirectFlag, NcDirectFlag_u64];
    crate::unit_impl_ops![bitwise; NcDirectFlag, NcDirectFlag_u64];
    crate::unit_impl_fmt![bases+display; NcDirectFlag];
}

pub(crate) mod c_api {
    use crate::c_api::ffi;

    /// A bitmask of [`NcDirect`][crate::NcDirect] flags.
    ///
    /// It's recommended to use [`NcDirectFlag`][crate::NcDirectFlag] instead.
    ///
    /// # Associated `c_api` constants
    /// - [`NCDIRECT_OPTION_DRAIN_INPUT`]
    /// - [`NCDIRECT_OPTION_INHIBIT_CBREAK`]
    /// - [`NCDIRECT_OPTION_INHIBIT_SETLOCALE`]
    /// - [`NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS`]
    /// - [`NCDIRECT_OPTION_VERBOSE`]
    /// - [`NCDIRECT_OPTION_VERY_VERBOSE`]
    pub type NcDirectFlag_u64 = u64;

    /// [`NcDirectFlag_u64`] flag that indicates input may be freely dropped.
    ///
    /// This ought be provided when the program does not intend to handle input.
    /// Otherwise, input can accumulate in internal buffers, eventually
    /// preventing *notcurses* from processing terminal messages.
    pub const NCDIRECT_OPTION_DRAIN_INPUT: NcDirectFlag_u64 =
        ffi::NCDIRECT_OPTION_DRAIN_INPUT as NcDirectFlag_u64;

    /// [`NcDirectFlag_u64`] flag to avoid placing the terminal into cbreak
    /// mode (disabling echo and line buffering)
    pub const NCDIRECT_OPTION_INHIBIT_CBREAK: NcDirectFlag_u64 =
        ffi::NCDIRECT_OPTION_INHIBIT_CBREAK as NcDirectFlag_u64;

    /// [`NcDirectFlag_u64`] flag to avoid calling setlocale(LC_ALL, NULL)
    ///
    /// If the result is either "C" or "POSIX", it will print a
    /// diagnostic to stderr, and then call setlocale(LC_ALL, "").
    ///
    /// This will attempt to set the locale based off the LANG
    /// environment variable. Your program should call setlocale(3)
    /// itself, usually as one of the first lines.
    ///
    pub const NCDIRECT_OPTION_INHIBIT_SETLOCALE: NcDirectFlag_u64 =
        ffi::NCDIRECT_OPTION_INHIBIT_SETLOCALE as NcDirectFlag_u64;

    /// [`NcDirectFlag_u64`] flag that inhibits registration of the `SIGINT`,
    /// `SIGSEGV`, `SIGABRT` & `SIGQUIT` signal handlers.
    pub const NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS: NcDirectFlag_u64 =
        ffi::NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS as NcDirectFlag_u64;

    /// [`NcDirectFlag_u64`] flag that enables showing detailed information.
    pub const NCDIRECT_OPTION_VERBOSE: NcDirectFlag_u64 =
        ffi::NCDIRECT_OPTION_VERBOSE as NcDirectFlag_u64;

    /// [`NcDirectFlag_u64`] flag that enables showing all diagnostics
    /// (equivalent to [`NCLOGLEVEL_TRACE`]).
    /// Implies [`NCDIRECT_OPTION_VERBOSE`].
    ///
    /// [`NCLOGLEVEL_TRACE`]: crate::c_api::NCLOGLEVEL_TRACE
    pub const NCDIRECT_OPTION_VERY_VERBOSE: NcDirectFlag_u64 =
        ffi::NCDIRECT_OPTION_VERY_VERBOSE as NcDirectFlag_u64;
}