1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //! Error of sync
15 
16 use std::error::Error;
17 use std::fmt::{Debug, Display, Formatter};
18 
19 /// Error returned by `send`
20 #[derive(Debug, Eq, PartialEq)]
21 pub struct SendError<T>(pub T);
22 
23 impl<T> Display for SendError<T> {
fmtnull24     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
25         write!(f, "channel is closed")
26     }
27 }
28 
29 impl<T: Debug> Error for SendError<T> {}
30 
31 /// Error returned by `recv`
32 #[derive(Debug, Eq, PartialEq)]
33 pub struct RecvError;
34 
35 impl Display for RecvError {
fmtnull36     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
37         write!(f, "channel is closed")
38     }
39 }
40 
41 impl Error for RecvError {}
42 
43 /// Error returned by `try_send`.
44 #[derive(Debug, Eq, PartialEq)]
45 pub enum TrySendError<T> {
46     /// The channel is full now.
47     Full(T),
48     /// The receiver of channel was closed or dropped.
49     Closed(T),
50 }
51 
52 impl<T> Display for TrySendError<T> {
fmtnull53     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54         match self {
55             TrySendError::Full(_) => write!(f, "channel is full"),
56             TrySendError::Closed(_) => write!(f, "channel is closed"),
57         }
58     }
59 }
60 
61 impl<T: Debug> Error for TrySendError<T> {}
62 
63 /// Error returned by `try_recv`.
64 #[derive(Debug, Eq, PartialEq, Clone)]
65 pub enum TryRecvError {
66     /// sender has not sent a value yet.
67     Empty,
68     /// sender was dropped.
69     Closed,
70 }
71 
72 impl Display for TryRecvError {
fmtnull73     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
74         match self {
75             TryRecvError::Empty => write!(f, "channel is empty"),
76             TryRecvError::Closed => write!(f, "channel is closed"),
77         }
78     }
79 }
80 
81 impl Error for TryRecvError {}
82 
83 cfg_time! {
84 
85     /// Error returned by `send_timeout`
86     #[derive(Debug,Eq,PartialEq)]
87     pub enum SendTimeoutError<T> {
88         /// The receiver of channel was closed or dropped.
89         Closed(T),
90         /// Sending timeout.
91         TimeOut(T),
92     }
93 
94     impl<T> Display for SendTimeoutError<T> {
fmtnull95         fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96             match self {
97                 SendTimeoutError::Closed(_) => write!(f, "channel is closed"),
98                 SendTimeoutError::TimeOut(_) => write!(f, "channel sending timeout"),
99             }
100         }
101     }
102     impl<T: Debug> Error for SendTimeoutError<T> {}
103 
104     /// Error returned by `recv_timeout`.
105     #[derive(Debug, Eq, PartialEq)]
106     pub enum RecvTimeoutError {
107         /// sender was dropped.
108         Closed,
109         /// Receiving timeout.
110         Timeout,
111     }
112 
113     impl Display for RecvTimeoutError {
fmtnull114         fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
115             match self {
116                 RecvTimeoutError::Closed => write!(f, "channel is closed"),
117                 RecvTimeoutError::Timeout => write!(f, "channel receiving timeout"),
118             }
119         }
120     }
121 
122     impl Error for RecvTimeoutError {}
123 }
124 
125 #[cfg(test)]
126 #[cfg(feature = "time")]
127 mod test {
128     use crate::sync::error::{RecvError, RecvTimeoutError, TryRecvError};
129 
130     /// UT test cases for Error.
131     ///
132     /// # Brief
133     /// 1. create two JoinHandle
134     /// 2. check the correctness of the JoinHandle for completion
135     #[test]
ut_test_sync_error_displaynull136     fn ut_test_sync_error_display() {
137         let recv_err = RecvError;
138         assert_eq!(format!("{recv_err}"), "channel is closed");
139 
140         let try_recv_err1 = TryRecvError::Empty;
141         assert_eq!(format!("{try_recv_err1}"), "channel is empty");
142         let try_recv_err2 = TryRecvError::Closed;
143         assert_eq!(format!("{try_recv_err2}"), "channel is closed");
144 
145         let try_timeout1 = RecvTimeoutError::Closed;
146         assert_eq!(format!("{try_timeout1}"), "channel is closed");
147         let try_timeout2 = RecvTimeoutError::Timeout;
148         assert_eq!(format!("{try_timeout2}"), "channel receiving timeout");
149     }
150 }
151