1use core::cmp;
2use core::fmt;
3use core::hash;
4use core::ptr;
5use core::slice;
6use core::str;
7
8use crate::bindings::{ngx_pool_t, ngx_str_t};
9use crate::detail;
10
11impl ngx_str_t {
12 #[inline]
17 pub fn as_bytes(&self) -> &[u8] {
18 if self.is_empty() {
19 &[]
20 } else {
21 unsafe { slice::from_raw_parts(self.data, self.len) }
23 }
24 }
25
26 #[inline]
28 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
29 if self.is_empty() {
30 &mut []
31 } else {
32 unsafe { slice::from_raw_parts_mut(self.data, self.len) }
34 }
35 }
36
37 #[inline]
39 pub fn is_empty(&self) -> bool {
40 self.len == 0
41 }
42
43 pub fn to_str(&self) -> &str {
51 str::from_utf8(self.as_bytes()).unwrap()
52 }
53
54 pub const fn empty() -> Self {
58 ngx_str_t {
59 len: 0,
60 data: ptr::null_mut(),
61 }
62 }
63
64 pub unsafe fn from_bytes(pool: *mut ngx_pool_t, src: &[u8]) -> Option<Self> {
70 detail::bytes_to_uchar(pool, src).map(|data| Self {
71 data,
72 len: src.len(),
73 })
74 }
75
76 pub unsafe fn from_str(pool: *mut ngx_pool_t, data: &str) -> Self {
91 ngx_str_t {
92 data: detail::str_to_uchar(pool, data),
93 len: data.len(),
94 }
95 }
96}
97
98impl AsRef<[u8]> for ngx_str_t {
99 fn as_ref(&self) -> &[u8] {
100 self.as_bytes()
101 }
102}
103
104impl AsMut<[u8]> for ngx_str_t {
105 fn as_mut(&mut self) -> &mut [u8] {
106 self.as_bytes_mut()
107 }
108}
109
110impl Default for ngx_str_t {
111 fn default() -> Self {
112 Self::empty()
113 }
114}
115
116impl fmt::Display for ngx_str_t {
117 #[inline]
118 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
119 detail::display_bytes(f, self.as_bytes())
120 }
121}
122
123impl From<ngx_str_t> for &[u8] {
124 fn from(s: ngx_str_t) -> Self {
125 if s.len == 0 || s.data.is_null() {
126 return Default::default();
127 }
128 unsafe { slice::from_raw_parts(s.data, s.len) }
129 }
130}
131
132impl hash::Hash for ngx_str_t {
133 fn hash<H: hash::Hasher>(&self, state: &mut H) {
134 self.as_bytes().hash(state)
135 }
136}
137
138impl PartialEq for ngx_str_t {
139 fn eq(&self, other: &Self) -> bool {
140 PartialEq::eq(self.as_bytes(), other.as_bytes())
141 }
142}
143
144impl Eq for ngx_str_t {}
145
146impl PartialOrd<Self> for ngx_str_t {
147 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
148 Some(self.cmp(other))
149 }
150}
151
152impl Ord for ngx_str_t {
153 fn cmp(&self, other: &Self) -> cmp::Ordering {
154 Ord::cmp(self.as_bytes(), other.as_bytes())
155 }
156}
157
158impl TryFrom<ngx_str_t> for &str {
159 type Error = str::Utf8Error;
160
161 fn try_from(s: ngx_str_t) -> Result<Self, Self::Error> {
162 str::from_utf8(s.into())
163 }
164}