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
use std::ffi::{CStr, CString, FromBytesWithNulError};
use std::ops::{Deref, Index, RangeFull};
use std::hash::{Hash, Hasher};
use std::borrow::Borrow;
use std::str::{from_utf8, Utf8Error};
use handle::Handle;
use ibytes::IBytes;
use istr::IStr;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct ICStr(pub(crate) Handle);
impl ICStr {
pub fn new(src: &CStr) -> Self {
ICStr(Handle::new(src.to_bytes_with_nul()))
}
pub fn from_bytes_with_nul(src: &[u8]) -> Result<Self, FromBytesWithNulError> {
CStr::from_bytes_with_nul(src).map(ICStr::new)
}
#[inline]
pub fn as_cstr(&self) -> &CStr {
unsafe {
CStr::from_bytes_with_nul_unchecked(self.0.get())
}
}
#[inline]
pub fn as_bytes(&self) -> &[u8] {
let length = self.0.get().len();
&self.0.get()[..length - 1]
}
#[inline]
pub fn as_bytes_with_nul(&self) -> &[u8] {
self.0.get()
}
#[inline]
pub fn to_ibytes_with_nul(&self) -> IBytes {
IBytes(self.0.clone())
}
#[inline]
pub fn to_istr(&self) -> Result<IStr, Utf8Error> {
from_utf8(self.as_bytes()).map(|_| IStr(self.0.clone()))
}
}
impl Deref for ICStr {
type Target = CStr;
#[inline]
fn deref(&self) -> &CStr {
self.as_cstr()
}
}
impl From<CString> for ICStr {
fn from(v: CString) -> Self {
ICStr::new(&v)
}
}
impl<'a> From<&'a CStr> for ICStr {
fn from(v: &'a CStr) -> Self {
ICStr::new(v)
}
}
impl From<Box<CStr>> for ICStr {
fn from(v: Box<CStr>) -> Self {
ICStr::new(&v)
}
}
impl Default for ICStr {
#[inline]
fn default() -> Self {
ICStr::new(Default::default())
}
}
impl Hash for ICStr {
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.as_cstr().hash(hasher)
}
}
impl Borrow<CStr> for ICStr {
#[inline]
fn borrow(&self) -> &CStr {
self.as_cstr()
}
}
impl Index<RangeFull> for ICStr {
type Output = CStr;
#[inline]
fn index(&self, _index: RangeFull) -> &CStr {
self.as_cstr()
}
}
impl AsRef<CStr> for ICStr {
#[inline]
fn as_ref(&self) -> &CStr {
self.as_cstr()
}
}