2222//! and `impl Write for ::alloc::vec::Vec<u8>` are provided
2323//!
2424
25+ #[ cfg( feature = "std" ) ]
26+ use std:: boxed:: Box as AllocBox ;
27+
28+ #[ cfg( not( feature = "std" ) ) ]
29+ use alloc:: boxed:: Box as AllocBox ;
30+
2531/// The Read trait allows for reading bytes from a source.
2632pub trait Read {
2733 /// The error type returned in Result
28- type Error ;
34+ type Error : ErrorTrait ;
35+
2936 /// see [std::io::Read::read]
3037 fn read ( & mut self , buf : & mut [ u8 ] ) -> :: core:: result:: Result < usize , Self :: Error > ;
38+
3139 /// see [std::io::Read::read_exact]
3240 fn read_exact ( & mut self , buf : & mut [ u8 ] ) -> :: core:: result:: Result < ( ) , Self :: Error > ;
3341}
3442
3543/// The Write trait allows to write bytes in the object implementing it.
3644pub trait Write {
3745 /// The error type returned in Result
38- type Error ;
46+ type Error : ErrorTrait ;
47+
3948 /// see [std::io::Write::write]
4049 fn write ( & mut self , buf : & [ u8 ] ) -> :: core:: result:: Result < usize , Self :: Error > ;
50+
4151 /// see [std::io::Write::write_all]
4252 fn write_all ( & mut self , buf : & [ u8 ] ) -> :: core:: result:: Result < ( ) , Self :: Error > ;
53+
4354 /// see [std::io::Write::flush]
4455 fn flush ( & mut self ) -> :: core:: result:: Result < ( ) , Self :: Error > ;
4556}
4657
58+ /// The literacy Error trait, custom errors must implement this
59+ pub trait ErrorTrait {
60+ /// The error category
61+ fn kind ( & self ) -> ErrorKind ;
62+ }
63+
64+ /// Same as [std::io::ErrorKind] that we have to duplicate because ErrorKind is not in `core`
65+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
66+ #[ allow( missing_docs) ]
67+ pub enum ErrorKind {
68+ NotFound ,
69+ PermissionDenied ,
70+ ConnectionRefused ,
71+ ConnectionReset ,
72+ ConnectionAborted ,
73+ NotConnected ,
74+ AddrInUse ,
75+ AddrNotAvailable ,
76+ BrokenPipe ,
77+ AlreadyExists ,
78+ WouldBlock ,
79+ InvalidInput ,
80+ InvalidData ,
81+ TimedOut ,
82+ WriteZero ,
83+ Interrupted ,
84+ Other ,
85+ UnexpectedEof ,
86+ }
87+
88+ /// The Error type in case we are not using [std::io::Error] or [core2::io::Error]
89+ #[ derive( Debug ) ]
90+ pub struct Error {
91+ kind : ErrorKind ,
92+
93+ error : AllocBox < dyn InnerError > ,
94+ }
95+
96+ trait InnerError : :: core:: fmt:: Debug + :: core:: any:: Any { }
97+
98+ impl InnerError for ( ) { }
99+
100+ impl ErrorTrait for Error {
101+ fn kind ( & self ) -> ErrorKind {
102+ self . kind
103+ }
104+ }
105+
47106#[ cfg( all( feature = "std" , not( feature = "use-core2" ) ) ) ]
48- pub use :: std:: io:: Error ;
107+ impl ErrorTrait for :: std:: io:: Error {
108+ fn kind ( & self ) -> ErrorKind {
109+ match self . kind ( ) {
110+ :: std:: io:: ErrorKind :: NotFound => ErrorKind :: NotFound ,
111+ :: std:: io:: ErrorKind :: PermissionDenied => ErrorKind :: PermissionDenied ,
112+ :: std:: io:: ErrorKind :: ConnectionRefused => ErrorKind :: ConnectionRefused ,
113+ :: std:: io:: ErrorKind :: ConnectionReset => ErrorKind :: ConnectionReset ,
114+ :: std:: io:: ErrorKind :: ConnectionAborted => ErrorKind :: ConnectionAborted ,
115+ :: std:: io:: ErrorKind :: NotConnected => ErrorKind :: NotConnected ,
116+ :: std:: io:: ErrorKind :: AddrInUse => ErrorKind :: AddrInUse ,
117+ :: std:: io:: ErrorKind :: AddrNotAvailable => ErrorKind :: AddrNotAvailable ,
118+ :: std:: io:: ErrorKind :: BrokenPipe => ErrorKind :: BrokenPipe ,
119+ :: std:: io:: ErrorKind :: AlreadyExists => ErrorKind :: AlreadyExists ,
120+ :: std:: io:: ErrorKind :: WouldBlock => ErrorKind :: WouldBlock ,
121+ :: std:: io:: ErrorKind :: InvalidInput => ErrorKind :: InvalidInput ,
122+ :: std:: io:: ErrorKind :: InvalidData => ErrorKind :: InvalidData ,
123+ :: std:: io:: ErrorKind :: TimedOut => ErrorKind :: TimedOut ,
124+ :: std:: io:: ErrorKind :: WriteZero => ErrorKind :: WriteZero ,
125+ :: std:: io:: ErrorKind :: Interrupted => ErrorKind :: Interrupted ,
126+ :: std:: io:: ErrorKind :: Other => ErrorKind :: Other ,
127+ :: std:: io:: ErrorKind :: UnexpectedEof => ErrorKind :: UnexpectedEof ,
128+ _ => ErrorKind :: Other ,
129+ }
130+ }
131+ }
49132
50133#[ cfg( all( feature = "std" , not( feature = "use-core2" ) ) ) ]
51134mod std_impl {
@@ -81,7 +164,31 @@ mod std_impl {
81164}
82165
83166#[ cfg( feature = "use-core2" ) ]
84- pub use core2:: io:: Error ;
167+ impl ErrorTrait for core2:: io:: Error {
168+ fn kind ( & self ) -> ErrorKind {
169+ match self . kind ( ) {
170+ core2:: io:: ErrorKind :: NotFound => ErrorKind :: NotFound ,
171+ core2:: io:: ErrorKind :: PermissionDenied => ErrorKind :: PermissionDenied ,
172+ core2:: io:: ErrorKind :: ConnectionRefused => ErrorKind :: ConnectionRefused ,
173+ core2:: io:: ErrorKind :: ConnectionReset => ErrorKind :: ConnectionReset ,
174+ core2:: io:: ErrorKind :: ConnectionAborted => ErrorKind :: ConnectionAborted ,
175+ core2:: io:: ErrorKind :: NotConnected => ErrorKind :: NotConnected ,
176+ core2:: io:: ErrorKind :: AddrInUse => ErrorKind :: AddrInUse ,
177+ core2:: io:: ErrorKind :: AddrNotAvailable => ErrorKind :: AddrNotAvailable ,
178+ core2:: io:: ErrorKind :: BrokenPipe => ErrorKind :: BrokenPipe ,
179+ core2:: io:: ErrorKind :: AlreadyExists => ErrorKind :: AlreadyExists ,
180+ core2:: io:: ErrorKind :: WouldBlock => ErrorKind :: WouldBlock ,
181+ core2:: io:: ErrorKind :: InvalidInput => ErrorKind :: InvalidInput ,
182+ core2:: io:: ErrorKind :: InvalidData => ErrorKind :: InvalidData ,
183+ core2:: io:: ErrorKind :: TimedOut => ErrorKind :: TimedOut ,
184+ core2:: io:: ErrorKind :: WriteZero => ErrorKind :: WriteZero ,
185+ core2:: io:: ErrorKind :: Interrupted => ErrorKind :: Interrupted ,
186+ core2:: io:: ErrorKind :: Other => ErrorKind :: Other ,
187+ core2:: io:: ErrorKind :: UnexpectedEof => ErrorKind :: UnexpectedEof ,
188+ _ => ErrorKind :: Other ,
189+ }
190+ }
191+ }
85192
86193#[ cfg( feature = "use-core2" ) ]
87194mod core2_impl {
@@ -116,17 +223,9 @@ mod core2_impl {
116223 }
117224}
118225
119- #[ cfg( all( not( feature = "use-core2" ) , not( feature = "std" ) ) ) ]
120- #[ derive( Debug ) ]
121- /// The Error for the default implementation
122- pub enum Error {
123- /// Unexpected "end of file"
124- UnexpectedEof ,
125- }
126-
127226#[ cfg( all( not( feature = "use-core2" ) , not( feature = "std" ) ) ) ]
128227mod default_impl {
129- use super :: { Read , Write , Error } ;
228+ use super :: { Read , Write , Error , ErrorKind } ;
130229
131230 impl < ' a > Read for & ' a [ u8 ] {
132231 type Error = Error ;
@@ -150,7 +249,10 @@ mod default_impl {
150249
151250 fn read_exact ( & mut self , buf : & mut [ u8 ] ) -> :: core:: result:: Result < ( ) , Self :: Error > {
152251 if buf. len ( ) > self . len ( ) {
153- return Err ( Self :: Error :: UnexpectedEof ) ;
252+ return Err ( Self :: Error {
253+ kind : ErrorKind :: UnexpectedEof ,
254+ error : alloc:: boxed:: Box :: new ( ( ) ) ,
255+ } ) ;
154256 }
155257 let ( a, b) = self . split_at ( buf. len ( ) ) ;
156258
0 commit comments