]> git.lizzy.rs Git - rust.git/blob - library/std/src/ffi/c_str/tests.rs
Constantify some slice methods
[rust.git] / library / std / src / ffi / c_str / tests.rs
1 use super::*;
2 use crate::borrow::Cow::{Borrowed, Owned};
3 use crate::collections::hash_map::DefaultHasher;
4 use crate::hash::{Hash, Hasher};
5 use crate::os::raw::c_char;
6 use crate::rc::Rc;
7 use crate::sync::Arc;
8
9 #[test]
10 fn c_to_rust() {
11     let data = b"123\0";
12     let ptr = data.as_ptr() as *const c_char;
13     unsafe {
14         assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123");
15         assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0");
16     }
17 }
18
19 #[test]
20 fn simple() {
21     let s = CString::new("1234").unwrap();
22     assert_eq!(s.as_bytes(), b"1234");
23     assert_eq!(s.as_bytes_with_nul(), b"1234\0");
24 }
25
26 #[test]
27 fn build_with_zero1() {
28     assert!(CString::new(&b"\0"[..]).is_err());
29 }
30 #[test]
31 fn build_with_zero2() {
32     assert!(CString::new(vec![0]).is_err());
33 }
34
35 #[test]
36 fn build_with_zero3() {
37     unsafe {
38         let s = CString::from_vec_unchecked(vec![0]);
39         assert_eq!(s.as_bytes(), b"\0");
40     }
41 }
42
43 #[test]
44 fn formatted() {
45     let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap();
46     assert_eq!(format!("{:?}", s), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#);
47 }
48
49 #[test]
50 fn borrowed() {
51     unsafe {
52         let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
53         assert_eq!(s.to_bytes(), b"12");
54         assert_eq!(s.to_bytes_with_nul(), b"12\0");
55     }
56 }
57
58 #[test]
59 fn to_str() {
60     let data = b"123\xE2\x80\xA6\0";
61     let ptr = data.as_ptr() as *const c_char;
62     unsafe {
63         assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…"));
64         assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…"));
65     }
66     let data = b"123\xE2\0";
67     let ptr = data.as_ptr() as *const c_char;
68     unsafe {
69         assert!(CStr::from_ptr(ptr).to_str().is_err());
70         assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}")));
71     }
72 }
73
74 #[test]
75 fn to_owned() {
76     let data = b"123\0";
77     let ptr = data.as_ptr() as *const c_char;
78
79     let owned = unsafe { CStr::from_ptr(ptr).to_owned() };
80     assert_eq!(owned.as_bytes_with_nul(), data);
81 }
82
83 #[test]
84 fn equal_hash() {
85     let data = b"123\xE2\xFA\xA6\0";
86     let ptr = data.as_ptr() as *const c_char;
87     let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) };
88
89     let mut s = DefaultHasher::new();
90     cstr.hash(&mut s);
91     let cstr_hash = s.finish();
92     let mut s = DefaultHasher::new();
93     CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s);
94     let cstring_hash = s.finish();
95
96     assert_eq!(cstr_hash, cstring_hash);
97 }
98
99 #[test]
100 fn from_bytes_with_nul() {
101     let data = b"123\0";
102     let cstr = CStr::from_bytes_with_nul(data);
103     assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..]));
104     let cstr = CStr::from_bytes_with_nul(data);
105     assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..]));
106
107     unsafe {
108         let cstr = CStr::from_bytes_with_nul(data);
109         let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
110         assert_eq!(cstr, Ok(cstr_unchecked));
111     }
112 }
113
114 #[test]
115 fn from_bytes_with_nul_unterminated() {
116     let data = b"123";
117     let cstr = CStr::from_bytes_with_nul(data);
118     assert!(cstr.is_err());
119 }
120
121 #[test]
122 fn from_bytes_with_nul_interior() {
123     let data = b"1\023\0";
124     let cstr = CStr::from_bytes_with_nul(data);
125     assert!(cstr.is_err());
126 }
127
128 #[test]
129 fn into_boxed() {
130     let orig: &[u8] = b"Hello, world!\0";
131     let cstr = CStr::from_bytes_with_nul(orig).unwrap();
132     let boxed: Box<CStr> = Box::from(cstr);
133     let cstring = cstr.to_owned().into_boxed_c_str().into_c_string();
134     assert_eq!(cstr, &*boxed);
135     assert_eq!(&*boxed, &*cstring);
136     assert_eq!(&*cstring, cstr);
137 }
138
139 #[test]
140 fn boxed_default() {
141     let boxed = <Box<CStr>>::default();
142     assert_eq!(boxed.to_bytes_with_nul(), &[0]);
143 }
144
145 #[test]
146 fn test_c_str_clone_into() {
147     let mut c_string = CString::new("lorem").unwrap();
148     let c_ptr = c_string.as_ptr();
149     let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap();
150     c_str.clone_into(&mut c_string);
151     assert_eq!(c_str, c_string.as_c_str());
152     // The exact same size shouldn't have needed to move its allocation
153     assert_eq!(c_ptr, c_string.as_ptr());
154 }
155
156 #[test]
157 fn into_rc() {
158     let orig: &[u8] = b"Hello, world!\0";
159     let cstr = CStr::from_bytes_with_nul(orig).unwrap();
160     let rc: Rc<CStr> = Rc::from(cstr);
161     let arc: Arc<CStr> = Arc::from(cstr);
162
163     assert_eq!(&*rc, cstr);
164     assert_eq!(&*arc, cstr);
165
166     let rc2: Rc<CStr> = Rc::from(cstr.to_owned());
167     let arc2: Arc<CStr> = Arc::from(cstr.to_owned());
168
169     assert_eq!(&*rc2, cstr);
170     assert_eq!(&*arc2, cstr);
171 }
172
173 #[test]
174 fn cstr_const_constructor() {
175     const CSTR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0") };
176
177     assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
178 }
179
180 #[test]
181 fn cstr_index_from() {
182     let original = b"Hello, world!\0";
183     let cstr = CStr::from_bytes_with_nul(original).unwrap();
184     let result = CStr::from_bytes_with_nul(&original[7..]).unwrap();
185
186     assert_eq!(&cstr[7..], result);
187 }
188
189 #[test]
190 #[should_panic]
191 fn cstr_index_from_empty() {
192     let original = b"Hello, world!\0";
193     let cstr = CStr::from_bytes_with_nul(original).unwrap();
194     let _ = &cstr[original.len()..];
195 }