pub use crate::generated::{
    TerminalControlCharacters, TerminalInputOptions, TerminalLineOptions, TerminalOptions,
    TerminalOutputOptions, TerminalSize,
};

impl TerminalControlCharacters {
    /// const-version of [Default] trait impl
    pub const fn const_default() -> Self {
        Self {
            eof: 0x04,
            erase: 0x7F,
            interrupt: 0x03,
            kill: 0x15,
            werase: 0x17,
        }
    }
}

impl TerminalLineOptions {
    /// Returns the line options used for raw tty input
    pub const fn raw_input() -> Self {
        Self::empty()
    }
}

impl TerminalOptions {
    /// const-version of [Default] trait impl
    pub const fn const_default() -> Self {
        Self {
            output: TerminalOutputOptions::const_default(),
            input: TerminalInputOptions::const_default(),
            line: TerminalLineOptions::const_default(),
            chars: TerminalControlCharacters::const_default(),
            baud_rate: 115200,
        }
    }

    /// Returns terminal options configured for raw tty input
    pub const fn raw_input() -> Self {
        Self {
            line: TerminalLineOptions::raw_input(),
            ..Self::const_default()
        }
    }

    /// Returns `true` if CANONICAL flag is set for this terminal
    pub const fn is_canonical(&self) -> bool {
        self.line.contains(TerminalLineOptions::CANONICAL)
    }

    /// Returns `true` if the terminal echoes the '\n' character
    pub fn is_echo_newline(&self) -> bool {
        self.line.contains_any(
            TerminalLineOptions::CANONICAL
                | TerminalLineOptions::ECHO
                | TerminalLineOptions::ECHO_NL,
        )
    }
}

impl Default for TerminalOptions {
    fn default() -> Self {
        Self::const_default()
    }
}

abi_serde::impl_newtype_serde!(TerminalLineOptions);
abi_serde::impl_newtype_serde!(TerminalInputOptions);
abi_serde::impl_newtype_serde!(TerminalOutputOptions);
abi_serde::impl_struct_serde!(TerminalControlCharacters: [
    eof, kill, erase, werase, interrupt
]);
abi_serde::impl_struct_serde!(TerminalOptions: [
    line, input, output, chars, baud_rate
]);
abi_serde::impl_struct_serde!(TerminalSize: [
    rows, columns
]);
