Skip to content

Commit a2f1fb4

Browse files
feat(uri): make Authority/PathAndQuery::from_static const
1 parent 8be6742 commit a2f1fb4

File tree

2 files changed

+153
-6
lines changed

2 files changed

+153
-6
lines changed

src/uri/authority.rs

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,95 @@ impl Authority {
4545
/// let authority = Authority::from_static("example.com");
4646
/// assert_eq!(authority.host(), "example.com");
4747
/// ```
48-
pub fn from_static(src: &'static str) -> Self {
49-
Authority::from_shared(Bytes::from_static(src.as_bytes()))
50-
.expect("static str is not valid authority")
48+
#[inline]
49+
#[allow(unconditional_panic)]
50+
pub const fn from_static(src: &'static str) -> Self {
51+
let bytes = src.as_bytes();
52+
53+
if bytes.len() == 0 {
54+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
55+
([] as [u8; 0])[0];
56+
}
57+
58+
let mut colon_cnt: u32 = 0;
59+
let mut start_bracket: bool = false;
60+
let mut end_bracket: bool = false;
61+
let mut has_percent: bool = false;
62+
let mut at_sign_pos: usize = bytes.len();
63+
const MAX_COLONS: u32 = 8;
64+
65+
let mut i: usize = 0;
66+
while i < bytes.len() {
67+
let b = bytes[i];
68+
69+
if b == b'/' || b == b'?' || b == b'#' {
70+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
71+
([] as [u8; 0])[0];
72+
}
73+
74+
let ch = URI_CHARS[b as usize];
75+
if ch == 0 {
76+
if b == b'%' {
77+
has_percent = true;
78+
} else {
79+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
80+
([] as [u8; 0])[0];
81+
}
82+
} else if ch == b':' {
83+
if colon_cnt >= MAX_COLONS {
84+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
85+
([] as [u8; 0])[0];
86+
}
87+
colon_cnt += 1;
88+
} else if ch == b'[' {
89+
if has_percent || start_bracket {
90+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
91+
([] as [u8; 0])[0];
92+
}
93+
start_bracket = true;
94+
} else if ch == b']' {
95+
if !start_bracket || end_bracket {
96+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
97+
([] as [u8; 0])[0];
98+
}
99+
end_bracket = true;
100+
101+
// Forget IPv6 internals
102+
colon_cnt = 0;
103+
has_percent = false;
104+
} else if ch == b'@' {
105+
at_sign_pos = i;
106+
107+
colon_cnt = 0;
108+
has_percent = false;
109+
}
110+
111+
i += 1;
112+
}
113+
114+
if (start_bracket && !end_bracket) || (!start_bracket && end_bracket) {
115+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
116+
([] as [u8; 0])[0];
117+
}
118+
119+
if colon_cnt > 1 {
120+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
121+
([] as [u8; 0])[0];
122+
}
123+
124+
if bytes.len() > 0 && at_sign_pos == bytes.len() - 1 {
125+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
126+
([] as [u8; 0])[0];
127+
}
128+
129+
if has_percent {
130+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
131+
([] as [u8; 0])[0];
132+
}
133+
134+
Authority {
135+
data: ByteStr::from_static(src),
136+
}
51137
}
52138

53139
/// Attempt to convert a `Bytes` buffer to a `Authority`.

src/uri/path.rs

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,71 @@ impl PathAndQuery {
138138
/// assert_eq!(v.query(), Some("world"));
139139
/// ```
140140
#[inline]
141-
pub fn from_static(src: &'static str) -> Self {
142-
let src = Bytes::from_static(src.as_bytes());
141+
#[allow(unconditional_panic)]
142+
pub const fn from_static(src: &'static str) -> Self {
143+
let bytes = src.as_bytes();
144+
let mut query: u16 = NONE;
145+
146+
// path ...
147+
let mut i: usize = 0;
148+
while i < bytes.len() {
149+
let b = bytes[i];
150+
if b == b'?' {
151+
query = i as u16;
152+
i += 1;
153+
break;
154+
} else if b == b'#' {
155+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
156+
([] as [u8; 0])[0];
157+
} else {
158+
let allowed = b == 0x21
159+
|| (b >= 0x24 && b <= 0x3B)
160+
|| b == 0x3D
161+
|| (b >= 0x40 && b <= 0x5F)
162+
|| (b >= 0x61 && b <= 0x7A)
163+
|| b == 0x7C
164+
|| b == 0x7E
165+
|| b == b'"'
166+
|| b == b'{'
167+
|| b == b'}'
168+
|| (b >= 0x7F);
169+
170+
if !allowed {
171+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
172+
([] as [u8; 0])[0];
173+
}
174+
}
175+
i += 1;
176+
}
143177

144-
PathAndQuery::from_shared(src).unwrap()
178+
// query ...
179+
if query != NONE {
180+
while i < bytes.len() {
181+
let b = bytes[i];
182+
if b == b'#' {
183+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
184+
([] as [u8; 0])[0];
185+
}
186+
187+
let allowed = b == 0x21
188+
|| (b >= 0x24 && b <= 0x3B)
189+
|| b == 0x3D
190+
|| (b >= 0x3F && b <= 0x7E)
191+
|| (b >= 0x7F);
192+
193+
if !allowed {
194+
#[allow(clippy::no_effect, clippy::out_of_bounds_indexing)]
195+
([] as [u8; 0])[0];
196+
}
197+
198+
i += 1;
199+
}
200+
}
201+
202+
PathAndQuery {
203+
data: ByteStr::from_static(src),
204+
query,
205+
}
145206
}
146207

147208
/// Attempt to convert a `Bytes` buffer to a `PathAndQuery`.

0 commit comments

Comments
 (0)