1#[cfg(test)]
12use std::ffi::CString;
13use std::{
14 error::Error,
15 ffi::NulError,
16 fmt::{Display, Formatter, Result as FmtResult}
17};
18
19#[derive(Debug)]
21pub enum CStringArrayError {
22 NulError(NulError),
24 EmptyArray
26}
27
28impl Display for CStringArrayError {
29 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
30 use CStringArrayError::*;
31 match self {
32 NulError(e) => {
33 write!(
34 f,
35 "String contains interior null byte at position {}",
36 e.nul_position()
37 )
38 }
39 EmptyArray => write!(f, "Cannot create array from empty input")
40 }
41 }
42}
43
44impl Error for CStringArrayError {
45 fn source(&self) -> Option<&(dyn Error + 'static)> {
46 use CStringArrayError::*;
47 match self {
48 NulError(e) => Some(e),
49 EmptyArray => None
50 }
51 }
52}
53
54impl From<NulError> for CStringArrayError {
55 fn from(err: NulError) -> Self {
56 Self::NulError(err)
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_nul_error_display() {
66 let test_string = "hello\0world";
67 let nul_err = match CString::new(test_string) {
68 Err(e) => e,
69 Ok(_) => panic!("Expected NulError")
70 };
71
72 let err = CStringArrayError::from(nul_err);
73 let display = format!("{}", err);
74 assert!(display.contains("interior null byte"));
75 assert!(display.contains("position 5"));
76 }
77
78 #[test]
79 fn test_empty_array_display() {
80 use CStringArrayError::*;
81 let err = EmptyArray;
82 assert_eq!(format!("{}", err), "Cannot create array from empty input");
83 }
84
85 #[test]
86 fn test_error_source_nul() {
87 let test_string = "test\0data";
88 let nul_err = CString::new(test_string).unwrap_err();
89 let err = CStringArrayError::from(nul_err);
90
91 assert!(err.source().is_some());
92 let source = err.source().unwrap();
93 assert!(source.is::<NulError>());
94 }
95
96 #[test]
97 fn test_error_source_empty() {
98 use CStringArrayError::*;
99 let err = EmptyArray;
100 assert!(err.source().is_none());
101 }
102
103 #[test]
104 fn test_from_nul_error() {
105 use CStringArrayError::*;
106 let nul_err = CString::new("a\0b").unwrap_err();
107 let err: CStringArrayError = nul_err.into();
108
109 match err {
110 NulError(e) => {
111 assert_eq!(e.nul_position(), 1);
112 }
113 _ => panic!("Expected NulError variant")
114 }
115 }
116
117 #[test]
118 fn test_debug_format() {
119 use CStringArrayError::*;
120 let err1 = EmptyArray;
121 let debug_str = format!("{:?}", err1);
122 assert!(debug_str.contains("EmptyArray"));
123
124 let nul_err = CString::new("x\0y").unwrap_err();
125 let err2 = CStringArrayError::from(nul_err);
126 let debug_str2 = format!("{:?}", err2);
127 assert!(debug_str2.contains("NulError"));
128 }
129}