uapi 0.2.0

Wrappers for OS APIs on UNIX-like platform
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
use std::{
    borrow::Borrow,
    convert::{TryFrom, TryInto},
    ffi::{CStr, CString, OsStr, OsString},
    mem::MaybeUninit,
    path::{Path, PathBuf},
};
use uapi::*;

fn ar<T: ?Sized, U: AsRef<T> + ?Sized>(t: &U) -> &T {
    t.as_ref()
}

fn am<T: ?Sized, U: AsMut<T> + ?Sized>(t: &mut U) -> &mut T {
    t.as_mut()
}

fn from<T: From<U>, U>(u: U) -> T {
    u.into()
}

fn try_from<T: TryFrom<U>, U>(u: U) -> std::result::Result<T, T::Error> {
    u.try_into()
}

#[test]
fn bstr() {
    assert_eq!(Bstr::empty(), "");
    assert_eq!(Bstr::empty(), Bstr::from_str(""));
    assert_eq!(Bstr::from_str("abc"), Bstr::from_bytes(b"abc"));
    assert_eq!(Bstr::from_path(Path::new("abc")), Bstr::from_bytes(b"abc"));
    assert_eq!(Bstr::from_os_str("abc".as_ref()), Bstr::from_bytes(b"abc"));
    assert_eq!(
        Bstr::from_bytes_mut(&mut [b'a', b'b', b'c']),
        Bstr::from_bytes(b"abc")
    );
    assert_eq!(
        Bstr::from_bytes_mut(&mut [b'a', b'b', b'c']).as_bytes_mut(),
        b"abc"
    );
    assert_eq!(&**Bstr::from_bytes_mut(&mut [b'a', b'b', b'c']), b"abc");
    assert_eq!(&**Bstr::from_bytes(b"abc"), b"abc");
    assert_eq!(Bstr::from_bytes(b"abc").as_str(), Ok("abc"));
    assert_eq!(Bstr::from_bytes(b"abc").as_os_str(), OsStr::new("abc"));
    assert_eq!(Bstr::from_bytes(b"abc").as_path(), Path::new("abc"));
    assert_eq!(Bstr::from_bytes(b"abc").len(), 3);
    assert!(Bstr::from_bytes(b"").is_empty());
    assert_eq!(Bstr::from_bytes(b"abc").to_ustring(), format_ustr!("abc"));
    assert_eq!(Bstr::from_bytes(b"abc").to_owned(), format_ustr!("abc"));

    let buf = &mut [b'a', b'b', b'c'];

    assert_eq!(Bstr::from_bytes(buf).as_ptr(), buf.as_ptr() as _);
    assert_eq!(
        Bstr::from_bytes_mut(buf).as_mut_ptr(),
        buf.as_mut_ptr() as _
    );

    assert_eq!(am::<[u8], _>(Bstr::from_bytes_mut(buf)), ustr!("abc"));
    assert_eq!(ar::<[u8], _>(Bstr::from_bytes(b"abc")), ustr!("abc"));
    assert_eq!(ar::<OsStr, _>(Bstr::from_bytes(b"abc")), ustr!("abc"));
    assert_eq!(ar::<Path, _>(Bstr::from_bytes(b"abc")), ustr!("abc"));
    assert_eq!(Bstr::from_bytes(b"abc").bytes(), ustr!("abc"));
    assert_eq!(format!("{:?}", Bstr::from_bytes(b"abc")), "\"abc\"");
    assert_eq!(format!("{}", Bstr::from_bytes(b"abc").display()), "abc");

    {
        let buf = &mut [b'a', b'b', b'c'];
        let bs = Bstr::from_bytes_mut(buf);
        bs[0] = b'd';
        assert_eq!(bs, "dbc");
    }

    assert_eq!(ar::<Bstr, _>(ustr!("abc").as_c_str().unwrap()), "abc");
}

#[test]
fn ustr() {
    assert_eq!(Ustr::empty(), "");
    assert_eq!(Ustr::empty(), Bstr::from_str(""));
    assert_eq!(Ustr::null(), "");
    assert!(Ustr::null().is_null());
    assert_eq!(Ustr::from_str("abc\0").unwrap(), "abc");
    assert_eq!(Ustr::from_str("abc"), None);
    unsafe {
        assert_eq!(
            Ustr::from_bytes_unchecked(&mut [b'a', b'b', b'c', 0]),
            "abc"
        );
    }
    assert_eq!(Ustr::from_bytes(b"abc\0").unwrap(), "abc");
    assert_eq!(Ustr::from_bytes(b"abc"), None);
    assert_eq!(Ustr::from_bytes(b"abc\0").unwrap().as_bytes(), b"abc");
    assert_eq!(
        Ustr::from_bytes(b"abc\0").unwrap().as_bytes_with_nul(),
        b"abc\0"
    );
    assert_eq!(
        Ustr::from_bytes(b"abc\0").unwrap().as_bytes_with_nul(),
        b"abc\0"
    );
    assert_eq!(
        Ustr::from_c_str(CStr::from_bytes_with_nul(b"abc\0").unwrap()),
        "abc"
    );
    {
        let buf = &mut [b'a', b'b', b'c', 0][..];
        assert_eq!(Ustr::from_bytes_mut(buf).unwrap(), "abc");
        assert_eq!(Ustr::from_bytes_mut(&mut []), None);
        unsafe {
            assert_eq!(Ustr::from_ptr(buf.as_ptr() as _), "abc");
        }
        unsafe {
            assert_eq!(Ustr::from_ptr_mut(buf.as_mut_ptr() as _), "abc");
        }
        // assert_eq!(Ustr::from_bytes_mut(buf).as_b_(), "abc");
    }
    assert_eq!(Ustr::from_os_str(OsStr::new("abc\0")).unwrap(), "abc");
    assert_eq!(Ustr::from_os_str(OsStr::new("abc")), None);
    assert_eq!(Ustr::from_path(Path::new("abc\0")).unwrap(), "abc");
    assert_eq!(Ustr::from_path(Path::new("abc")), None);
    assert_eq!(ustr!("abc").as_os_str_with_nul(), "abc\0");
    assert_eq!(ustr!("abc").as_path_with_nul().as_os_str(), "abc\0");
    assert!(!Ustr::empty().as_ptr_null().is_null());
    assert!(Ustr::null().as_ptr_null().is_null());
    assert_eq!(ustr!("abc").to_owned(), format!("abc"));

    let buf = &mut [b'a', b'b', b'c', 0][..];
    assert_eq!(
        am::<[u8], _>(Ustr::from_bytes_mut(buf).unwrap()),
        ustr!("abc")
    );
    assert_eq!(ar::<[u8], _>(ustr!("abc")), ustr!("abc"));
    assert_eq!(ar::<OsStr, _>(ustr!("abc")), ustr!("abc"));
    assert_eq!(ar::<Path, _>(ustr!("abc")), ustr!("abc"));
    assert_eq!(
        ar::<Ustr, _>(CStr::from_bytes_with_nul(b"abc\0").unwrap()),
        ustr!("abc")
    );

    assert_eq!(format!("{:?}", ustr!("abc")), "\"abc\"");
}

#[test]
fn ustring() {
    {
        let mut us = Ustring::new();
        assert_eq!(us.len(), 0);
        assert_eq!(us.capacity(), 0);
        us.reserve(1);
        assert_eq!(us.len(), 0);
        assert!(us.capacity() >= 1);
        us.reserve_exact(31);
        assert_eq!(us.len(), 0);
        assert!(us.capacity() >= 31);
        unsafe {
            us.with_unused(|b| {
                assert!(b.len() >= 31);
                b[0] = MaybeUninit::new(b'1');
                Ok(1)
            })
            .unwrap();
        }
        assert_eq!(us.len(), 1);
        assert_eq!(&us, "1");
        unsafe {
            let _ = us.with_unused(|b| {
                (0..b.len()).for_each(|i| b[i] = MaybeUninit::new(1));
                Err(Errno(0))
            });
        }
        unsafe {
            assert_eq!(Ustr::from_ptr(us.as_ptr()), "1");
        }
    }

    assert_eq!(&Ustring::from_vec(vec!()), "");
    assert_eq!(&Ustring::from_vec_with_nul(vec!()).unwrap(), "");
    assert_eq!(&Ustring::from_vec_with_nul(vec!(b'1', 0)).unwrap(), "1");
    unsafe {
        assert_eq!(&Ustring::from_vec_with_nul_unchecked(vec!()), "");
        assert_eq!(&Ustring::from_vec_with_nul_unchecked(vec!(0)), "");
    }
    assert!(Ustring::from_vec_with_nul(vec!(b'1')).is_err());
    assert_eq!(
        Ustring::from_vec_with_nul(vec!(b'1', 0))
            .unwrap()
            .into_vec(),
        vec!(b'1')
    );
    assert_eq!(
        Ustring::from_vec_with_nul(vec!())
            .unwrap()
            .into_vec_with_nul(),
        vec!(0)
    );

    assert_eq!(&Ustring::from_string("".to_string()), "");
    assert_eq!(&Ustring::from_string_with_nul("".to_string()).unwrap(), "");
    assert_eq!(
        &Ustring::from_string_with_nul("1\0".to_string()).unwrap(),
        "1"
    );
    assert!(Ustring::from_string_with_nul("1".to_string()).is_err());
    assert_eq!(
        Ustring::from_string_with_nul("1\0".to_string())
            .unwrap()
            .into_string()
            .unwrap(),
        "1".to_string()
    );
    assert_eq!(
        Ustring::from_string_with_nul("1\0".to_string())
            .unwrap()
            .into_string_with_nul()
            .unwrap(),
        "1\0".to_string()
    );
    assert!(Bstr::from_bytes(b"\xff")
        .to_ustring()
        .into_string()
        .is_err());
    assert!(Bstr::from_bytes(b"\xff")
        .to_ustring()
        .into_string_with_nul()
        .is_err());

    assert_eq!(&Ustring::from_c_string(CString::new("abc").unwrap()), "abc");
    assert_eq!(
        ustr!("abc").to_ustring().into_c_string().unwrap().as_ustr(),
        "abc"
    );
    assert!(ustr!("a\0bc").to_ustring().into_c_string().is_err());

    assert_eq!(
        &Ustring::from_os_string(OsStr::new("abc").to_os_string()),
        "abc"
    );
    assert!(&Ustring::from_os_string_with_nul(OsStr::new("abc").to_os_string()).is_err());
    assert_eq!(
        &Ustring::from_os_string_with_nul(OsStr::new("abc\0").to_os_string()).unwrap(),
        "abc"
    );
    assert_eq!(ustr!("abc").to_ustring().into_os_string(), "abc");
    assert_eq!(ustr!("abc").to_ustring().into_os_string_with_nul(), "abc\0");

    assert_eq!(
        &Ustring::from_path_buf(Path::new("abc").to_path_buf()),
        "abc"
    );
    assert!(&Ustring::from_path_buf_with_nul(Path::new("abc").to_path_buf()).is_err());
    assert_eq!(
        &Ustring::from_path_buf_with_nul(Path::new("abc\0").to_path_buf()).unwrap(),
        "abc"
    );
    assert_eq!(ustr!("abc").to_ustring().into_path_buf().as_os_str(), "abc");
    assert_eq!(
        ustr!("abc")
            .to_ustring()
            .into_path_buf_with_nul()
            .as_os_str(),
        "abc\0"
    );

    assert_eq!(ustr!("abc").to_ustring().as_ustr_mut(), "abc");

    assert_eq!(Ustring::new(), Ustring::default());

    let us = ustr!("abc").to_ustring();
    {
        let b: &Bstr = us.borrow();
        assert_eq!(b, "abc");
    }

    {
        let b: &Ustr = us.borrow();
        assert_eq!(b, "abc");
    }

    assert_eq!(&from::<Ustring, _>(vec!(b'a')), "a");
    assert_eq!(&from::<Ustring, _>("a".to_string()), "a");
    assert_eq!(&from::<Ustring, _>(OsStr::new("a").to_os_string()), "a");
    assert_eq!(&from::<Ustring, _>(Path::new("a").to_path_buf()), "a");
    assert_eq!(&from::<Ustring, _>(CString::new("a").unwrap()), "a");
    assert_eq!(&from::<Vec<u8>, _>(ustr!("a").to_ustring()), b"a");
    assert_eq!(&from::<OsString, _>(ustr!("a").to_ustring()), "a");
    assert_eq!(from::<PathBuf, _>(ustr!("a").to_ustring()).as_os_str(), "a");

    assert_eq!(am::<[u8], _>(&mut format_ustr!("abc")), ustr!("abc"));
    assert_eq!(ar::<[u8], _>(&format_ustr!("abc")), ustr!("abc"));
    assert_eq!(ar::<OsStr, _>(&format_ustr!("abc")), ustr!("abc"));
    assert_eq!(ar::<Path, _>(&format_ustr!("abc")), ustr!("abc"));

    assert_eq!(format!("{:?}", format_ustr!("abc")), "\"abc\"");

    assert_eq!(&**format_ustr!("abc"), "abc");
    assert_eq!(&mut **format_ustr!("abc"), "abc");

    assert_eq!(
        try_from::<String, _>(format_ustr!("a")).unwrap(),
        format!("a")
    );
    assert!(
        try_from::<String, _>(Ustr::from_bytes(b"\xff\0").unwrap().to_ustring()).is_err()
    );

    assert_eq!(
        try_from::<CString, _>(format_ustr!("a")).unwrap(),
        CString::new("a").unwrap()
    );
    assert!(try_from::<CString, _>(format_ustr!("\0")).is_err());
}

#[test]
fn ustrptr() {
    let mut buf = UstrPtr::default();

    buf.push("abc");
    buf.extend(["def"].iter().copied());

    unsafe {
        assert_eq!(CStr::from_ptr(*buf.as_ptr()).as_ustr(), "abc");
        assert_eq!(
            CStr::from_ptr(*(buf.as_ptr() as *const *const c::c_char).add(1)).as_ustr(),
            "def"
        );
        assert!((*(buf.as_ptr() as *const *const c::c_char).add(2)).is_null());
    }

    let buf: UstrPtr = ["abc"].iter().copied().collect();

    unsafe {
        assert_eq!(CStr::from_ptr(*buf.as_ptr()).as_ustr(), "abc");
        assert!((*(buf.as_ptr() as *const *const c::c_char).add(1)).is_null());
    }
}

#[test]
fn read() {
    let vec = format!("abc").into_bytes();
    let mut buf = &vec[..];

    assert_eq!(&UapiReadExt::read_to_new_ustring(&mut buf).unwrap(), "abc");

    let mut buf = &vec[..];

    let mut us = Ustring::new();
    assert_eq!(UapiReadExt::read_to_ustring(&mut buf, &mut us).unwrap(), 3);
    assert_eq!(&us, "abc");
}

#[test]
fn into() {
    assert_eq!(&"a".into_ustr().to_ustring(), "a");
    assert_eq!(&"a".to_string().into_ustr().to_ustring(), "a");
    assert_eq!(&"a".as_bytes().into_ustr().to_ustring(), "a");
    assert_eq!(&"a".to_string().into_bytes().into_ustr().to_ustring(), "a");
    assert_eq!(&ustr!("a").as_bstr().into_ustr().to_ustring(), "a");
    assert_eq!(&ustr!("a").into_ustr().to_ustring(), "a");
    assert_eq!(&ustr!("a").to_ustring().into_ustr().to_ustring(), "a");
    assert_eq!(&OsStr::new("a").into_ustr().to_ustring(), "a");
    assert_eq!(
        &OsStr::new("a").to_os_string().into_ustr().to_ustring(),
        "a"
    );
    assert_eq!(&Path::new("a").into_ustr().to_ustring(), "a");
    assert_eq!(&Path::new("a").to_path_buf().into_ustr().to_ustring(), "a");
    assert_eq!(
        &CStr::from_bytes_with_nul(b"a\0")
            .unwrap()
            .into_ustr()
            .to_ustring(),
        "a"
    );
    assert_eq!(
        &CStr::from_bytes_with_nul(b"a\0")
            .unwrap()
            .to_owned()
            .into_ustr()
            .to_ustring(),
        "a"
    );
    assert_eq!(&(&"a".into_ustr()).into_ustr().to_ustring(), "a");
    assert_eq!(&"a".into_ustr().into_ustr().to_ustring(), "a");
}

#[test]
fn eq() {
    macro_rules! c {
        ($e:expr) => {{
            assert_eq!($e, "a".as_bytes());
            assert_eq!("a".as_bytes(), $e);
            assert_eq!($e, "a");
            assert_eq!("a", $e);
            assert_eq!($e, CStr::from_bytes_with_nul(b"a\0").unwrap());
            assert_eq!(CStr::from_bytes_with_nul(b"a\0").unwrap(), $e);
            assert_eq!($e, OsStr::new("a"));
            assert_eq!(OsStr::new("a"), $e);
            assert_eq!($e, Path::new("a"));
            assert_eq!(Path::new("a"), $e);
            assert_eq!($e, &"a".to_string().into_bytes());
            assert_eq!(&"a".to_string().into_bytes(), $e);
            assert_eq!($e, &"a".to_string());
            assert_eq!(&"a".to_string(), $e);
            assert_eq!($e, &CStr::from_bytes_with_nul(b"a\0").unwrap().to_owned());
            assert_eq!(&CStr::from_bytes_with_nul(b"a\0").unwrap().to_owned(), $e);
            assert_eq!($e, &OsStr::new("a").to_owned());
            assert_eq!(&OsStr::new("a").to_owned(), $e);
            assert_eq!($e, &Path::new("a").to_owned());
            assert_eq!(&Path::new("a").to_owned(), $e);
            assert_eq!($e, ustr!("a"));
            assert_eq!(ustr!("a"), $e);
            assert_eq!($e, ustr!("a").as_bstr());
            assert_eq!(ustr!("a").as_bstr(), $e);
            assert_eq!($e, &ustr!("a").to_ustring());
            assert_eq!(&ustr!("a").to_ustring(), $e);
        }};
    }

    c!(ustr!("a"));
    c!(ustr!("a").as_bstr());
    c!(&ustr!("a").to_owned());
}

#[test]
fn bytes() {
    assert_eq!(ustr!("a").as_bstr().bytes(), b"a");
    assert_eq!(ustr!("a").into_ustr().bytes(), b"a");
    assert_eq!(Bytes::bytes("a"), b"a");
    assert_eq!("a".as_bytes().bytes(), b"a");
    assert_eq!(OsStr::new("a").bytes(), b"a");
    assert_eq!(Path::new("a").bytes(), b"a");
    assert_eq!(CStr::from_bytes_with_nul(b"a\0").unwrap().bytes(), b"a");
}

#[test]
fn as_ustr() {
    assert_eq!(ustr!("a").as_ustr(), "a");
    assert_eq!(AsUstr::as_ustr(&ustr!("a").to_ustring()), "a");
    assert_eq!(CStr::from_bytes_with_nul(b"a\0").unwrap().as_ustr(), "a");
    assert_eq!(
        CStr::from_bytes_with_nul(b"a\0")
            .unwrap()
            .to_owned()
            .as_ustr(),
        "a"
    );
}