use crate::{
alloc::CBox,
core::{
alloc::NSTDAllocError,
optional::{gen_optional, NSTDOptional},
result::NSTDResult,
slice::{NSTDSlice, NSTDSliceMut},
str::nstd_core_str_from_bytes_unchecked,
},
io::{NSTDIOError, NSTDIOResult},
string::{nstd_string_push_str, NSTDString},
vec::NSTDVec,
};
use nstdapi::nstdapi;
use std::io::{Stdin, StdinLock};
#[cfg(unix)]
use std::os::unix::io::AsRawFd;
#[nstdapi]
pub struct NSTDStdin {
r#in: CBox<Stdin>,
}
gen_optional!(NSTDOptionalStdin, NSTDStdin);
#[inline]
#[nstdapi]
pub fn nstd_io_stdin() -> NSTDOptionalStdin {
CBox::new(std::io::stdin()).map_or(NSTDOptional::None, |r#in| {
NSTDOptional::Some(NSTDStdin { r#in })
})
}
#[inline]
#[nstdapi]
pub unsafe fn nstd_io_stdin_read(
handle: &mut NSTDStdin,
buffer: &mut NSTDSliceMut,
) -> NSTDIOResult {
#[cfg(not(unix))]
return crate::io::stdio::read(&mut *handle.r#in, buffer);
#[cfg(unix)]
return crate::os::unix::io::stdio::read(handle.r#in.lock().as_raw_fd(), buffer).into();
}
#[inline]
#[nstdapi]
pub fn nstd_io_stdin_read_all(handle: &mut NSTDStdin, buffer: &mut NSTDVec<'_>) -> NSTDIOResult {
#[cfg(not(unix))]
return crate::io::stdio::read_all(&mut *handle.r#in, buffer);
#[cfg(unix)]
unsafe {
crate::os::unix::io::stdio::read_all(handle.r#in.lock().as_raw_fd(), buffer).into()
}
}
#[inline]
#[nstdapi]
pub fn nstd_io_stdin_read_to_string(
handle: &mut NSTDStdin,
buffer: &mut NSTDString<'_>,
) -> NSTDIOResult {
#[cfg(not(unix))]
return crate::io::stdio::read_to_string(&mut *handle.r#in, buffer);
#[cfg(unix)]
unsafe {
crate::os::unix::io::stdio::read_to_string(handle.r#in.lock().as_raw_fd(), buffer).into()
}
}
#[inline]
#[nstdapi]
pub unsafe fn nstd_io_stdin_read_exact(
handle: &mut NSTDStdin,
buffer: &mut NSTDSliceMut,
) -> NSTDIOError {
#[cfg(not(unix))]
return crate::io::stdio::read_exact(&mut *handle.r#in, buffer);
#[cfg(unix)]
return crate::os::unix::io::stdio::read_exact(handle.r#in.lock().as_raw_fd(), buffer).into();
}
#[nstdapi]
pub fn nstd_io_stdin_read_line(
handle: &mut NSTDStdin,
buffer: &mut NSTDString<'_>,
) -> NSTDIOResult {
let mut buf = String::new();
match handle.r#in.read_line(&mut buf) {
Ok(r) => {
let bytes = NSTDSlice::from_slice(buf.as_bytes());
unsafe {
let str = nstd_core_str_from_bytes_unchecked(&bytes);
match nstd_string_push_str(buffer, &str) {
NSTDAllocError::NSTD_ALLOC_ERROR_NONE => NSTDResult::Ok(r),
_ => NSTDResult::Err(NSTDIOError::NSTD_IO_ERROR_OUT_OF_MEMORY),
}
}
}
Err(err) => NSTDResult::Err(NSTDIOError::from_err(err.kind())),
}
}
#[inline]
#[nstdapi]
#[allow(
unused_variables,
clippy::missing_const_for_fn,
clippy::needless_pass_by_value
)]
pub fn nstd_io_stdin_free(handle: NSTDStdin) {}
#[nstdapi]
pub struct NSTDStdinLock {
r#in: CBox<StdinLock<'static>>,
}
gen_optional!(NSTDOptionalStdinLock, NSTDStdinLock);
#[inline]
#[nstdapi]
pub fn nstd_io_stdin_lock() -> NSTDOptionalStdinLock {
CBox::new(std::io::stdin().lock()).map_or(NSTDOptional::None, |r#in| {
NSTDOptional::Some(NSTDStdinLock { r#in })
})
}
#[inline]
#[nstdapi]
pub unsafe fn nstd_io_stdin_lock_read(
handle: &mut NSTDStdinLock,
buffer: &mut NSTDSliceMut,
) -> NSTDIOResult {
#[cfg(not(unix))]
return crate::io::stdio::read(&mut *handle.r#in, buffer);
#[cfg(unix)]
return crate::os::unix::io::stdio::read(handle.r#in.as_raw_fd(), buffer).into();
}
#[inline]
#[nstdapi]
pub fn nstd_io_stdin_lock_read_all(
handle: &mut NSTDStdinLock,
buffer: &mut NSTDVec<'_>,
) -> NSTDIOResult {
#[cfg(not(unix))]
return crate::io::stdio::read_all(&mut *handle.r#in, buffer);
#[cfg(unix)]
unsafe {
crate::os::unix::io::stdio::read_all(handle.r#in.as_raw_fd(), buffer).into()
}
}
#[inline]
#[nstdapi]
pub fn nstd_io_stdin_lock_read_to_string(
handle: &mut NSTDStdinLock,
buffer: &mut NSTDString<'_>,
) -> NSTDIOResult {
#[cfg(not(unix))]
return crate::io::stdio::read_to_string(&mut *handle.r#in, buffer);
#[cfg(unix)]
unsafe {
crate::os::unix::io::stdio::read_to_string(handle.r#in.as_raw_fd(), buffer).into()
}
}
#[inline]
#[nstdapi]
pub unsafe fn nstd_io_stdin_lock_read_exact(
handle: &mut NSTDStdinLock,
buffer: &mut NSTDSliceMut,
) -> NSTDIOError {
#[cfg(not(unix))]
return crate::io::stdio::read_exact(&mut *handle.r#in, buffer);
#[cfg(unix)]
return crate::os::unix::io::stdio::read_exact(handle.r#in.as_raw_fd(), buffer).into();
}
#[inline]
#[nstdapi]
#[allow(
unused_variables,
clippy::missing_const_for_fn,
clippy::needless_pass_by_value
)]
pub fn nstd_io_stdin_unlock(handle: NSTDStdinLock) {}