1pub mod stderr;
3pub mod stdin;
4pub(crate) mod stdio;
5pub mod stdout;
6#[cfg(unix)]
7use crate::os::unix::io::{
8 NSTDUnixIOError::{
9 self, NSTD_UNIX_IO_ERROR_BLOCKING, NSTD_UNIX_IO_ERROR_BROKEN_PIPE,
10 NSTD_UNIX_IO_ERROR_CONNECTION_RESET, NSTD_UNIX_IO_ERROR_INTERRUPTED,
11 NSTD_UNIX_IO_ERROR_INVALID_DATA, NSTD_UNIX_IO_ERROR_INVALID_INPUT, NSTD_UNIX_IO_ERROR_NONE,
12 NSTD_UNIX_IO_ERROR_NOT_FOUND, NSTD_UNIX_IO_ERROR_NO_CONNECTION,
13 NSTD_UNIX_IO_ERROR_OUT_OF_MEMORY, NSTD_UNIX_IO_ERROR_PERMISSION_DENIED,
14 NSTD_UNIX_IO_ERROR_TIMED_OUT, NSTD_UNIX_IO_ERROR_UNEXPECTED_EOF,
15 },
16 NSTDUnixIOResult,
17};
18use crate::{
19 core::{result::NSTDResult, str::NSTDStr},
20 string::{nstd_string_pop, NSTDString},
21 vec::NSTDVec,
22 NSTDUInt,
23};
24use nstdapi::nstdapi;
25use std::io::{ErrorKind, Write};
26
27#[nstdapi]
29#[derive(Clone, Copy, PartialEq, Eq)]
30#[allow(non_camel_case_types)]
31pub enum NSTDIOError {
32 NSTD_IO_ERROR_NONE,
34 NSTD_IO_ERROR_UNKNOWN,
36 NSTD_IO_ERROR_NOT_FOUND,
38 NSTD_IO_ERROR_PERMISSION_DENIED,
40 NSTD_IO_ERROR_CONNECTION_REFUSED,
42 NSTD_IO_ERROR_CONNECTION_RESET,
44 NSTD_IO_ERROR_CONNECTION_TERMINATED,
46 NSTD_IO_ERROR_NO_CONNECTION,
48 NSTD_IO_ERROR_SOCKET_IN_USE,
50 NSTD_IO_ERROR_ADDRESS_NOT_FOUND,
52 NSTD_IO_ERROR_BROKEN_PIPE,
54 NSTD_IO_ERROR_ALREADY_EXISTS,
56 NSTD_IO_ERROR_BLOCKING,
58 NSTD_IO_ERROR_INVALID_INPUT,
60 NSTD_IO_ERROR_INVALID_DATA,
62 NSTD_IO_ERROR_TIMED_OUT,
64 NSTD_IO_ERROR_WRITE_ZERO,
66 NSTD_IO_ERROR_INTERRUPTED,
68 NSTD_IO_ERROR_UNSUPPORTED,
70 NSTD_IO_ERROR_UNEXPECTED_EOF,
72 NSTD_IO_ERROR_OUT_OF_MEMORY,
74}
75impl NSTDIOError {
76 pub(crate) const fn from_err(err: ErrorKind) -> Self {
78 match err {
79 ErrorKind::NotFound => Self::NSTD_IO_ERROR_NOT_FOUND,
80 ErrorKind::PermissionDenied => Self::NSTD_IO_ERROR_PERMISSION_DENIED,
81 ErrorKind::ConnectionRefused => Self::NSTD_IO_ERROR_CONNECTION_REFUSED,
82 ErrorKind::ConnectionReset => Self::NSTD_IO_ERROR_CONNECTION_RESET,
83 ErrorKind::ConnectionAborted => Self::NSTD_IO_ERROR_CONNECTION_TERMINATED,
84 ErrorKind::NotConnected => Self::NSTD_IO_ERROR_NO_CONNECTION,
85 ErrorKind::AddrInUse => Self::NSTD_IO_ERROR_SOCKET_IN_USE,
86 ErrorKind::AddrNotAvailable => Self::NSTD_IO_ERROR_ADDRESS_NOT_FOUND,
87 ErrorKind::BrokenPipe => Self::NSTD_IO_ERROR_BROKEN_PIPE,
88 ErrorKind::AlreadyExists => Self::NSTD_IO_ERROR_ALREADY_EXISTS,
89 ErrorKind::WouldBlock => Self::NSTD_IO_ERROR_BLOCKING,
90 ErrorKind::InvalidInput => Self::NSTD_IO_ERROR_INVALID_INPUT,
91 ErrorKind::InvalidData => Self::NSTD_IO_ERROR_INVALID_DATA,
92 ErrorKind::TimedOut => Self::NSTD_IO_ERROR_TIMED_OUT,
93 ErrorKind::WriteZero => Self::NSTD_IO_ERROR_WRITE_ZERO,
94 ErrorKind::Interrupted => Self::NSTD_IO_ERROR_INTERRUPTED,
95 ErrorKind::Unsupported => Self::NSTD_IO_ERROR_UNSUPPORTED,
96 ErrorKind::UnexpectedEof => Self::NSTD_IO_ERROR_UNEXPECTED_EOF,
97 ErrorKind::OutOfMemory => Self::NSTD_IO_ERROR_OUT_OF_MEMORY,
98 _ => Self::NSTD_IO_ERROR_UNKNOWN,
99 }
100 }
101}
102#[cfg(unix)]
103impl From<NSTDUnixIOError> for NSTDIOError {
104 fn from(err: NSTDUnixIOError) -> Self {
106 match err {
107 NSTD_UNIX_IO_ERROR_NONE => Self::NSTD_IO_ERROR_NONE,
108 NSTD_UNIX_IO_ERROR_NOT_FOUND => Self::NSTD_IO_ERROR_NOT_FOUND,
109 NSTD_UNIX_IO_ERROR_PERMISSION_DENIED => Self::NSTD_IO_ERROR_PERMISSION_DENIED,
110 NSTD_UNIX_IO_ERROR_CONNECTION_RESET => Self::NSTD_IO_ERROR_CONNECTION_RESET,
111 NSTD_UNIX_IO_ERROR_NO_CONNECTION => Self::NSTD_IO_ERROR_NO_CONNECTION,
112 NSTD_UNIX_IO_ERROR_BROKEN_PIPE => Self::NSTD_IO_ERROR_BROKEN_PIPE,
113 NSTD_UNIX_IO_ERROR_BLOCKING => Self::NSTD_IO_ERROR_BLOCKING,
114 NSTD_UNIX_IO_ERROR_INVALID_INPUT => Self::NSTD_IO_ERROR_INVALID_INPUT,
115 NSTD_UNIX_IO_ERROR_INVALID_DATA => Self::NSTD_IO_ERROR_INVALID_DATA,
116 NSTD_UNIX_IO_ERROR_TIMED_OUT => Self::NSTD_IO_ERROR_TIMED_OUT,
117 NSTD_UNIX_IO_ERROR_INTERRUPTED => Self::NSTD_IO_ERROR_INTERRUPTED,
118 NSTD_UNIX_IO_ERROR_UNEXPECTED_EOF => Self::NSTD_IO_ERROR_UNEXPECTED_EOF,
119 NSTD_UNIX_IO_ERROR_OUT_OF_MEMORY => Self::NSTD_IO_ERROR_OUT_OF_MEMORY,
120 _ => Self::NSTD_IO_ERROR_UNKNOWN,
121 }
122 }
123}
124
125pub type NSTDIOResult = NSTDResult<NSTDUInt, NSTDIOError>;
128#[cfg(unix)]
129impl From<NSTDUnixIOResult> for NSTDIOResult {
130 #[inline]
132 fn from(value: NSTDUnixIOResult) -> Self {
133 match value {
134 NSTDResult::Ok(value) => Self::Ok(value),
135 NSTDResult::Err(err) => Self::Err(err.into()),
136 }
137 }
138}
139
140pub type NSTDIOBufferResult<'a> = NSTDResult<NSTDVec<'a>, NSTDIOError>;
142
143pub type NSTDIOStringResult<'a> = NSTDResult<NSTDString<'a>, NSTDIOError>;
145
146#[nstdapi]
161pub unsafe fn nstd_io_print(output: &NSTDStr) -> NSTDIOError {
162 let mut stdout = std::io::stdout();
163 if let Err(err) = stdout.write_all(output.as_str().as_bytes()) {
164 return NSTDIOError::from_err(err.kind());
165 } else if let Err(err) = stdout.flush() {
166 return NSTDIOError::from_err(err.kind());
167 }
168 NSTDIOError::NSTD_IO_ERROR_NONE
169}
170
171#[nstdapi]
186pub unsafe fn nstd_io_print_line(output: &NSTDStr) -> NSTDIOError {
187 let mut stdout = std::io::stdout();
188 if let Err(err) = stdout.write_all(output.as_str().as_bytes()) {
189 return NSTDIOError::from_err(err.kind());
190 } else if let Err(err) = stdout.write_all(b"\n") {
191 return NSTDIOError::from_err(err.kind());
192 } else if let Err(err) = stdout.flush() {
193 return NSTDIOError::from_err(err.kind());
194 }
195 NSTDIOError::NSTD_IO_ERROR_NONE
196}
197
198#[nstdapi]
205pub fn nstd_io_read() -> NSTDIOStringResult<'static> {
206 let mut res = nstd_io_read_line();
207 if let NSTDResult::Ok(input) = &mut res {
208 nstd_string_pop(input);
209 }
210 res
211}
212
213#[nstdapi]
220pub fn nstd_io_read_line() -> NSTDIOStringResult<'static> {
221 let mut input = String::new();
223 match std::io::stdin().read_line(&mut input) {
224 Ok(_) => NSTDResult::Ok(NSTDString::from_string(input)),
225 Err(err) => NSTDResult::Err(NSTDIOError::from_err(err.kind())),
226 }
227}