use mingling::{ Groupped, macros::{r_println, renderer}, res::ResExitCode, }; use crate::locale::errors::I18nIoError; pub const EC_IOERR_NOT_FOUND: i32 = 2500; pub const EC_IOERR_PERMISSION_DENIED: i32 = 2501; pub const EC_IOERR_CONNECTION_REFUSED: i32 = 2502; pub const EC_IOERR_CONNECTION_RESET: i32 = 2503; pub const EC_IOERR_HOST_UNREACHABLE: i32 = 2504; pub const EC_IOERR_NETWORK_UNREACHABLE: i32 = 2505; pub const EC_IOERR_CONNECTION_ABORTED: i32 = 2506; pub const EC_IOERR_NOT_CONNECTED: i32 = 2507; pub const EC_IOERR_ADDR_IN_USE: i32 = 2508; pub const EC_IOERR_ADDR_NOT_AVAILABLE: i32 = 2509; pub const EC_IOERR_NETWORK_DOWN: i32 = 2510; pub const EC_IOERR_BROKEN_PIPE: i32 = 2511; pub const EC_IOERR_ALREADY_EXISTS: i32 = 2512; pub const EC_IOERR_WOULD_BLOCK: i32 = 2513; pub const EC_IOERR_NOT_A_DIRECTORY: i32 = 2514; pub const EC_IOERR_IS_A_DIRECTORY: i32 = 2515; pub const EC_IOERR_DIRECTORY_NOT_EMPTY: i32 = 2516; pub const EC_IOERR_READ_ONLY_FILESYSTEM: i32 = 2517; pub const EC_IOERR_STALE_NETWORK_FILE_HANDLE: i32 = 2518; pub const EC_IOERR_INVALID_INPUT: i32 = 2519; pub const EC_IOERR_INVALID_DATA: i32 = 2520; pub const EC_IOERR_TIMED_OUT: i32 = 2521; pub const EC_IOERR_WRITE_ZERO: i32 = 2522; pub const EC_IOERR_STORAGE_FULL: i32 = 2523; pub const EC_IOERR_NOT_SEEKABLE: i32 = 2524; pub const EC_IOERR_QUOTA_EXCEEDED: i32 = 2525; pub const EC_IOERR_FILE_TOO_LARGE: i32 = 2526; pub const EC_IOERR_RESOURCE_BUSY: i32 = 2527; pub const EC_IOERR_EXECUTABLE_FILE_BUSY: i32 = 2528; pub const EC_IOERR_DEADLOCK: i32 = 2529; pub const EC_IOERR_CROSSES_DEVICES: i32 = 2530; pub const EC_IOERR_TOO_MANY_LINKS: i32 = 2531; pub const EC_IOERR_INVALID_FILENAME: i32 = 2532; pub const EC_IOERR_ARGUMENT_LIST_TOO_LONG: i32 = 2533; pub const EC_IOERR_INTERRUPTED: i32 = 2534; pub const EC_IOERR_UNSUPPORTED: i32 = 2535; pub const EC_IOERR_UNEXPECTED_EOF: i32 = 2536; pub const EC_IOERR_OUT_OF_MEMORY: i32 = 2537; pub const EC_IOERR_OTHER: i32 = 2538; #[derive(Default, Groupped)] pub enum ErrorIo { #[default] /// DONT USE IT: This variant is only used to provide a Default derive for ErrorIo /// /// In normal creation flow, you should directly use ErrorIo::from(/* std::io::Error */) DontUse, Error(std::io::Error), } #[renderer] pub fn render_error_io(err: ErrorIo, ec: &mut ResExitCode) { let err: std::io::Error = err.into(); let content = format!("{:?}", err); let (error_info, exit_code) = io_error_info(err, content); r_println!("{}{}", I18nIoError::io_error_name(), error_info); ec.exit_code = exit_code; } fn io_error_info(err: std::io::Error, content: String) -> (String, i32) { match err.kind() { std::io::ErrorKind::NotFound => (I18nIoError::not_found(content), EC_IOERR_NOT_FOUND), std::io::ErrorKind::PermissionDenied => ( I18nIoError::permission_denied(content), EC_IOERR_PERMISSION_DENIED, ), std::io::ErrorKind::ConnectionRefused => ( I18nIoError::connection_refused(content), EC_IOERR_CONNECTION_REFUSED, ), std::io::ErrorKind::ConnectionReset => ( I18nIoError::connection_reset(content), EC_IOERR_CONNECTION_RESET, ), std::io::ErrorKind::HostUnreachable => ( I18nIoError::host_unreachable(content), EC_IOERR_HOST_UNREACHABLE, ), std::io::ErrorKind::NetworkUnreachable => ( I18nIoError::network_unreachable(content), EC_IOERR_NETWORK_UNREACHABLE, ), std::io::ErrorKind::ConnectionAborted => ( I18nIoError::connection_aborted(content), EC_IOERR_CONNECTION_ABORTED, ), std::io::ErrorKind::NotConnected => { (I18nIoError::not_connected(content), EC_IOERR_NOT_CONNECTED) } std::io::ErrorKind::AddrInUse => (I18nIoError::addr_in_use(content), EC_IOERR_ADDR_IN_USE), std::io::ErrorKind::AddrNotAvailable => ( I18nIoError::addr_not_available(content), EC_IOERR_ADDR_NOT_AVAILABLE, ), std::io::ErrorKind::NetworkDown => { (I18nIoError::network_down(content), EC_IOERR_NETWORK_DOWN) } std::io::ErrorKind::BrokenPipe => (I18nIoError::broken_pipe(content), EC_IOERR_BROKEN_PIPE), std::io::ErrorKind::AlreadyExists => ( I18nIoError::already_exists(content), EC_IOERR_ALREADY_EXISTS, ), std::io::ErrorKind::WouldBlock => (I18nIoError::would_block(content), EC_IOERR_WOULD_BLOCK), std::io::ErrorKind::NotADirectory => ( I18nIoError::not_a_directory(content), EC_IOERR_NOT_A_DIRECTORY, ), std::io::ErrorKind::IsADirectory => ( I18nIoError::is_a_directory(content), EC_IOERR_IS_A_DIRECTORY, ), std::io::ErrorKind::DirectoryNotEmpty => ( I18nIoError::directory_not_empty(content), EC_IOERR_DIRECTORY_NOT_EMPTY, ), std::io::ErrorKind::ReadOnlyFilesystem => ( I18nIoError::read_only_filesystem(content), EC_IOERR_READ_ONLY_FILESYSTEM, ), std::io::ErrorKind::StaleNetworkFileHandle => ( I18nIoError::stale_network_file_handle(content), EC_IOERR_STALE_NETWORK_FILE_HANDLE, ), std::io::ErrorKind::InvalidInput => { (I18nIoError::invalid_input(content), EC_IOERR_INVALID_INPUT) } std::io::ErrorKind::InvalidData => { (I18nIoError::invalid_data(content), EC_IOERR_INVALID_DATA) } std::io::ErrorKind::TimedOut => (I18nIoError::timed_out(content), EC_IOERR_TIMED_OUT), std::io::ErrorKind::WriteZero => (I18nIoError::write_zero(content), EC_IOERR_WRITE_ZERO), std::io::ErrorKind::StorageFull => { (I18nIoError::storage_full(content), EC_IOERR_STORAGE_FULL) } std::io::ErrorKind::NotSeekable => { (I18nIoError::not_seekable(content), EC_IOERR_NOT_SEEKABLE) } std::io::ErrorKind::QuotaExceeded => ( I18nIoError::quota_exceeded(content), EC_IOERR_QUOTA_EXCEEDED, ), std::io::ErrorKind::FileTooLarge => ( I18nIoError::file_too_large(content), EC_IOERR_FILE_TOO_LARGE, ), std::io::ErrorKind::ResourceBusy => { (I18nIoError::resource_busy(content), EC_IOERR_RESOURCE_BUSY) } std::io::ErrorKind::ExecutableFileBusy => ( I18nIoError::executable_file_busy(content), EC_IOERR_EXECUTABLE_FILE_BUSY, ), std::io::ErrorKind::Deadlock => (I18nIoError::deadlock(content), EC_IOERR_DEADLOCK), std::io::ErrorKind::CrossesDevices => ( I18nIoError::crosses_devices(content), EC_IOERR_CROSSES_DEVICES, ), std::io::ErrorKind::TooManyLinks => ( I18nIoError::too_many_links(content), EC_IOERR_TOO_MANY_LINKS, ), std::io::ErrorKind::InvalidFilename => ( I18nIoError::invalid_filename(content), EC_IOERR_INVALID_FILENAME, ), std::io::ErrorKind::ArgumentListTooLong => ( I18nIoError::argument_list_too_long(content), EC_IOERR_ARGUMENT_LIST_TOO_LONG, ), std::io::ErrorKind::Interrupted => { (I18nIoError::interrupted(content), EC_IOERR_INTERRUPTED) } std::io::ErrorKind::Unsupported => { (I18nIoError::unsupported(content), EC_IOERR_UNSUPPORTED) } std::io::ErrorKind::UnexpectedEof => ( I18nIoError::unexpected_eof(content), EC_IOERR_UNEXPECTED_EOF, ), std::io::ErrorKind::OutOfMemory => { (I18nIoError::out_of_memory(content), EC_IOERR_OUT_OF_MEMORY) } std::io::ErrorKind::Other => (I18nIoError::other(content), EC_IOERR_OTHER), _ => (I18nIoError::other(content), EC_IOERR_OTHER), } } impl From for ErrorIo { fn from(err: std::io::Error) -> Self { ErrorIo::Error(err) } } impl From for std::io::Error { fn from(err: ErrorIo) -> Self { match err { ErrorIo::Error(err) => err, ErrorIo::DontUse => std::io::Error::other("Unknown error"), } } } impl std::ops::Deref for ErrorIo { type Target = std::io::Error; fn deref(&self) -> &Self::Target { match self { ErrorIo::Error(err) => err, ErrorIo::DontUse => panic!("Cannot deref ErrorIo::Unknown"), } } } impl std::ops::DerefMut for ErrorIo { fn deref_mut(&mut self) -> &mut Self::Target { match self { ErrorIo::Error(err) => err, ErrorIo::DontUse => panic!("Cannot deref_mut ErrorIo::Unknown"), } } } impl std::borrow::Borrow for ErrorIo { fn borrow(&self) -> &std::io::Error { match self { ErrorIo::Error(err) => err, ErrorIo::DontUse => panic!("Cannot borrow ErrorIo::Unknown"), } } }