pub fn read_console_output(console_output: &impl AsConsoleOutputHandle, buffer: &mut [CHAR_INFO], buffer_size: impl IntoCoord, buffer_coord: impl IntoCoord, read_region: &mut SMALL_RECT) -> io::Result<()> {
    let console_output = console_output.as_raw_handle().cast();
    let buffer_size = buffer_size.into_coord();
    let buffer_coord = buffer_coord.into_coord();

    // Bounds checking
    if buffer_coord.X > buffer_size.X { return Err(io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_coord.X > buffer_size.X")); }
    if buffer_coord.Y > buffer_size.Y { return Err(io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_coord.Y > buffer_size.Y")); }
    let buffer_w = usize::try_from(buffer_size.X).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_size.X is out of SHORT bounds"))?;
    let buffer_h = usize::try_from(buffer_size.Y).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_size.Y is out of SHORT bounds"))?;
    let buffer_size_total = buffer_w.checked_mul(buffer_h).ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_size.X * Y is out of usize bounds"))?;
    if buffer_size_total > buffer.len() { return Err(io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_size is larger than buffer")); }
    // TODO: read_region bounds checking?

    succeeded_to_result(unsafe { ReadConsoleOutputW(console_output, buffer.as_mut_ptr(), buffer_size, buffer_coord, read_region) })
}
/// \[[ReadConsoleOutputW]\] Reads character and color attribute data from a rectangular block of character cells in a console screen buffer, and the function writes the data to a rectangular block at a specified location in the destination buffer.
///
/// ### Example
/// ```
/// # use maulingmonkey_console_winapi_wrappers::*;
/// # use std::io::{self, *};
/// # let _ = (|| -> io::Result<()> {
/// use winapi::um::wincontypes::{CHAR_INFO, SMALL_RECT};
/// let mut buffer = [CHAR_INFO::default(); 80 * 25];
/// let mut region = SMALL_RECT { Left: 0, Right: 80, Top: 0, Bottom: 25 };
/// read_console_output(&stdout(), &mut buffer, (80,25), (0,0), &mut region)?;
/// # Ok(())
/// # })();
/// ```
///
/// [ReadConsoleOutputW]:   https://docs.microsoft.com/en-us/windows/console/readconsoleoutput
\[[ReadConsoleOutputW]\] Reads character and color attribute data from a rectangular block of character cells in a console screen buffer, and the function writes the data to a rectangular block at a specified location in the destination buffer.
\ [[ ReadConsoleOutputW ] \ ] Reads character and color attribute data from a rectangular block of character cells in a console screen buffer and the function writes the data to a rectangular block at a specified location in the destination buffer .
pub fn read_console_output(console_output: &impl AsConsoleOutputHandle, buffer: &mut [CHAR_INFO], buffer_size: impl IntoCoord, buffer_coord: impl IntoCoord, read_region: &mut SMALL_RECT) -> io::Result<()> {
    let console_output = console_output.as_raw_handle().cast();
    let buffer_size = buffer_size.into_coord();
    let buffer_coord = buffer_coord.into_coord();
    // Bounds checking
    if buffer_coord.X > buffer_size.X { return Err(io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_coord.X > buffer_size.X")); }
    if buffer_coord.Y > buffer_size.Y { return Err(io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_coord.Y > buffer_size.Y")); }
    let buffer_w = usize::try_from(buffer_size.X).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_size.X is out of SHORT bounds"))?;
    let buffer_h = usize::try_from(buffer_size.Y).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_size.Y is out of SHORT bounds"))?;
    let buffer_size_total = buffer_w.checked_mul(buffer_h).ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_size.X * Y is out of usize bounds"))?;
    if buffer_size_total > buffer.len() { return Err(io::Error::new(io::ErrorKind::InvalidInput, "read_console_output(): buffer_size is larger than buffer")); }
    // TODO: read_region bounds checking?
    succeeded_to_result(unsafe { ReadConsoleOutputW(console_output, buffer.as_mut_ptr(), buffer_size, buffer_coord, read_region) })
}
pub fn read_console_output ( console_output : & impl AsConsoleOutputHandle , buffer : & mut [ CHAR_INFO ] , buffer_size : impl IntoCoord , buffer_coord : impl IntoCoord , read_region : & mut SMALL_RECT ) -> io :: Result < ( ) > { let console_output = console_output . as_raw_handle ( ) . cast ( ) ; let buffer_size = buffer_size . into_coord ( ) ; let buffer_coord = buffer_coord . into_coord ( ) ; // Bounds checking if buffer_coord . X > buffer_size . X { return Err ( io :: Error :: new ( io :: ErrorKind :: InvalidInput , " " ) ) ; } if buffer_coord . Y > buffer_size . Y { return Err ( io :: Error :: new ( io :: ErrorKind :: InvalidInput , " " ) ) ; } let buffer_w = usize :: try_from ( buffer_size . X ) . map_err ( | _ | io :: Error :: new ( io :: ErrorKind :: InvalidInput , " " ) ) ? ; let buffer_h = usize :: try_from ( buffer_size . Y ) . map_err ( | _ | io :: Error :: new ( io :: ErrorKind :: InvalidInput , " " ) ) ? ; let buffer_size_total = buffer_w . checked_mul ( buffer_h ) . ok_or_else ( | | io :: Error :: new ( io :: ErrorKind :: InvalidInput , " " ) ) ? ; if buffer_size_total > buffer . len ( ) { return Err ( io :: Error :: new ( io :: ErrorKind :: InvalidInput , " " ) ) ; } // TODO: read_region bounds checking? succeeded_to_result ( unsafe { ReadConsoleOutputW ( console_output , buffer . as_mut_ptr ( ) , buffer_size , buffer_coord , read_region ) } ) }
\[[ReadConsoleOutputW]\] Reads character and color attribute data from a rectangular block of character cells in a console screen buffer, and the function writes the data to a rectangular block at a specified location in the destination buffer.
\ [[ ReadConsoleOutputW ] \ ] Reads character and color attribute data from a rectangular block of character cells in a console screen buffer and the function writes the data to a rectangular block at a specified location in the destination buffer .
console_output
&impl AsConsoleOutputHandle
buffer
&mut [CHAR_INFO]
buffer_size
impl IntoCoord
buffer_coord
impl IntoCoord
read_region
&mut SMALL_RECT
console_output
&impl AsConsoleOutputHandle
buffer
&mut [CHAR_INFO]
buffer_size
impl IntoCoord
buffer_coord
impl IntoCoord
read_region
&mut SMALL_RECT
example
None
use maulingmonkey_console_winapi_wrappers::*;
None
use std::io::{self, *};
None
let _ = (|| -> io::result<()> {
use winapi::um::wincontypes::{CHAR_INFO, SMALL_RECT};
let mut buffer = [CHAR_INFO::default(); 80 * 25];
let mut region = SMALL_RECT { Left: 0, Right: 80, Top: 0, Bottom: 25 };
read_console_output(&stdout(), &mut buffer, (80,25), (0,0), &mut region)?.
use winapi :: um :: wincontypes :: { CHAR_INFO SMALL_RECT } ; let mut buffer = [ CHAR_INFO :: default () ; 80 * 25 ] ; let mut region = SMALL_RECT { Left : 0 Right : 80 Top : 0 Bottom : 25 } ; read_console_output ( &stdout () &mut buffer ( 80 25 ) ( 0 0 ) &mut region ) ? .
ok(())
None
})();
None