Skip to content

Commit 000c9dd

Browse files
committed
Bring back TryFrom<Bytes> implementations
This is mostly a revert of commit 4ce5e6a, but this does not bring back the error variants suffixed with `Bytes` (db9b1b9). This also replaces usage of the internal `from_shared` associated functions with `try_from`. Reference: <#459>
1 parent 5b90e38 commit 000c9dd

File tree

7 files changed

+290
-153
lines changed

7 files changed

+290
-153
lines changed

benches/header_value.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
extern crate test;
44

5+
use std::convert::TryFrom;
6+
57
use bytes::Bytes;
68
use http::HeaderValue;
79
use test::Bencher;
@@ -14,7 +16,7 @@ fn from_shared_short(b: &mut Bencher) {
1416
b.bytes = SHORT.len() as u64;
1517
let bytes = Bytes::from_static(SHORT);
1618
b.iter(|| {
17-
HeaderValue::from_maybe_shared(bytes.clone()).unwrap();
19+
HeaderValue::try_from(bytes.clone()).unwrap();
1820
});
1921
}
2022

@@ -23,7 +25,7 @@ fn from_shared_long(b: &mut Bencher) {
2325
b.bytes = LONG.len() as u64;
2426
let bytes = Bytes::from_static(LONG);
2527
b.iter(|| {
26-
HeaderValue::from_maybe_shared(bytes.clone()).unwrap();
28+
HeaderValue::try_from(bytes.clone()).unwrap();
2729
});
2830
}
2931

src/header/name.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,14 @@ macro_rules! standard_headers {
118118
// Test lower case
119119
let name_bytes = name.as_bytes();
120120
let bytes: Bytes =
121-
HeaderName::from_bytes(name_bytes).unwrap().inner.into();
121+
HeaderName::from_bytes(name_bytes).unwrap().into();
122122
assert_eq!(bytes, name_bytes);
123123
assert_eq!(HeaderName::from_bytes(name_bytes).unwrap(), std);
124124

125125
// Test upper case
126126
let upper = name.to_uppercase().to_string();
127127
let bytes: Bytes =
128-
HeaderName::from_bytes(upper.as_bytes()).unwrap().inner.into();
128+
HeaderName::from_bytes(upper.as_bytes()).unwrap().into();
129129
assert_eq!(bytes, name.as_bytes());
130130
assert_eq!(HeaderName::from_bytes(upper.as_bytes()).unwrap(),
131131
std);
@@ -1800,10 +1800,6 @@ impl HeaderName {
18001800
Repr::Custom(ref v) => &*v.0,
18011801
}
18021802
}
1803-
1804-
pub(super) fn into_bytes(self) -> Bytes {
1805-
self.inner.into()
1806-
}
18071803
}
18081804

18091805
impl FromStr for HeaderName {
@@ -1876,6 +1872,13 @@ impl From<Custom> for Bytes {
18761872
}
18771873
}
18781874

1875+
impl From<HeaderName> for Bytes {
1876+
#[inline]
1877+
fn from(name: HeaderName) -> Bytes {
1878+
name.inner.into()
1879+
}
1880+
}
1881+
18791882
impl<'a> TryFrom<&'a str> for HeaderName {
18801883
type Error = InvalidHeaderName;
18811884
#[inline]
@@ -1900,6 +1903,14 @@ impl<'a> TryFrom<&'a [u8]> for HeaderName {
19001903
}
19011904
}
19021905

1906+
impl TryFrom<Bytes> for HeaderName {
1907+
type Error = InvalidHeaderName;
1908+
#[inline]
1909+
fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
1910+
Self::from_bytes(bytes.as_ref())
1911+
}
1912+
}
1913+
19031914
#[doc(hidden)]
19041915
impl From<StandardHeader> for HeaderName {
19051916
fn from(src: StandardHeader) -> HeaderName {

src/header/value.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ impl From<HeaderName> for HeaderValue {
372372
#[inline]
373373
fn from(h: HeaderName) -> HeaderValue {
374374
HeaderValue {
375-
inner: h.into_bytes(),
375+
inner: h.into(),
376376
is_sensitive: false,
377377
}
378378
}
@@ -490,6 +490,13 @@ impl FromStr for HeaderValue {
490490
}
491491
}
492492

493+
impl From<HeaderValue> for Bytes {
494+
#[inline]
495+
fn from(value: HeaderValue) -> Bytes {
496+
value.inner
497+
}
498+
}
499+
493500
impl<'a> From<&'a HeaderValue> for HeaderValue {
494501
#[inline]
495502
fn from(t: &'a HeaderValue) -> Self {
@@ -541,6 +548,15 @@ impl TryFrom<Vec<u8>> for HeaderValue {
541548
}
542549
}
543550

551+
impl TryFrom<Bytes> for HeaderValue {
552+
type Error = InvalidHeaderValue;
553+
554+
#[inline]
555+
fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
556+
HeaderValue::from_shared(bytes)
557+
}
558+
}
559+
544560
#[cfg(test)]
545561
mod try_from_header_name_tests {
546562
use super::*;

src/uri/authority.rs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,6 @@ impl Authority {
2121
}
2222
}
2323

24-
// Not public while `bytes` is unstable.
25-
pub(super) fn from_shared(s: Bytes) -> Result<Self, InvalidUri> {
26-
// Precondition on create_authority: trivially satisfied by the
27-
// identity clousre
28-
create_authority(s, |s| s)
29-
}
30-
3124
/// Attempt to convert an `Authority` from a static string.
3225
///
3326
/// This function will not perform any copying, and the string will be
@@ -46,7 +39,7 @@ impl Authority {
4639
/// assert_eq!(authority.host(), "example.com");
4740
/// ```
4841
pub fn from_static(src: &'static str) -> Self {
49-
Authority::from_shared(Bytes::from_static(src.as_bytes()))
42+
Authority::try_from(Bytes::from_static(src.as_bytes()))
5043
.expect("static str is not valid authority")
5144
}
5245

@@ -59,7 +52,7 @@ impl Authority {
5952
T: AsRef<[u8]> + 'static,
6053
{
6154
if_downcast_into!(T, Bytes, src, {
62-
return Authority::from_shared(src);
55+
return Authority::try_from(src);
6356
});
6457

6558
Authority::try_from(src.as_ref())
@@ -259,8 +252,33 @@ impl Authority {
259252
}
260253
}
261254

262-
// Purposefully not public while `bytes` is unstable.
263-
// impl TryFrom<Bytes> for Authority
255+
impl TryFrom<Bytes> for Authority {
256+
type Error = InvalidUri;
257+
/// Attempt to convert an `Authority` from `Bytes`.
258+
///
259+
/// # Examples
260+
///
261+
/// ```
262+
/// # extern crate http;
263+
/// # use http::uri::*;
264+
/// extern crate bytes;
265+
///
266+
/// use std::convert::TryFrom;
267+
/// use bytes::Bytes;
268+
///
269+
/// # pub fn main() {
270+
/// let bytes = Bytes::from("example.com");
271+
/// let authority = Authority::try_from(bytes).unwrap();
272+
///
273+
/// assert_eq!(authority.host(), "example.com");
274+
/// # }
275+
/// ```
276+
fn try_from(s: Bytes) -> Result<Self, Self::Error> {
277+
// Precondition on create_authority: trivially satisfied by the
278+
// identity clousre
279+
create_authority(s, |s| s)
280+
}
281+
}
264282

265283
impl AsRef<str> for Authority {
266284
fn as_ref(&self) -> &str {
@@ -450,6 +468,13 @@ impl FromStr for Authority {
450468
}
451469
}
452470

471+
impl From<Authority> for Bytes {
472+
#[inline]
473+
fn from(src: Authority) -> Bytes {
474+
src.data.into()
475+
}
476+
}
477+
453478
impl fmt::Debug for Authority {
454479
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
455480
f.write_str(self.as_str())
@@ -640,7 +665,7 @@ mod tests {
640665
let err = Authority::try_from([0xc0u8].as_ref()).unwrap_err();
641666
assert_eq!(err.0, ErrorKind::InvalidUriChar);
642667

643-
let err = Authority::from_shared(Bytes::from_static([0xc0u8].as_ref()))
668+
let err = Authority::try_from(Bytes::from_static([0xc0u8].as_ref()))
644669
.unwrap_err();
645670
assert_eq!(err.0, ErrorKind::InvalidUriChar);
646671
}

src/uri/mod.rs

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -250,63 +250,12 @@ impl Uri {
250250
T: AsRef<[u8]> + 'static,
251251
{
252252
if_downcast_into!(T, Bytes, src, {
253-
return Uri::from_shared(src);
253+
return Uri::try_from(src);
254254
});
255255

256256
Uri::try_from(src.as_ref())
257257
}
258258

259-
// Not public while `bytes` is unstable.
260-
fn from_shared(s: Bytes) -> Result<Uri, InvalidUri> {
261-
use self::ErrorKind::*;
262-
263-
if s.len() > MAX_LEN {
264-
return Err(TooLong.into());
265-
}
266-
267-
match s.len() {
268-
0 => {
269-
return Err(Empty.into());
270-
}
271-
1 => match s[0] {
272-
b'/' => {
273-
return Ok(Uri {
274-
scheme: Scheme::empty(),
275-
authority: Authority::empty(),
276-
path_and_query: PathAndQuery::slash(),
277-
});
278-
}
279-
b'*' => {
280-
return Ok(Uri {
281-
scheme: Scheme::empty(),
282-
authority: Authority::empty(),
283-
path_and_query: PathAndQuery::star(),
284-
});
285-
}
286-
_ => {
287-
let authority = Authority::from_shared(s)?;
288-
289-
return Ok(Uri {
290-
scheme: Scheme::empty(),
291-
authority: authority,
292-
path_and_query: PathAndQuery::empty(),
293-
});
294-
}
295-
},
296-
_ => {}
297-
}
298-
299-
if s[0] == b'/' {
300-
return Ok(Uri {
301-
scheme: Scheme::empty(),
302-
authority: Authority::empty(),
303-
path_and_query: PathAndQuery::from_shared(s)?,
304-
});
305-
}
306-
307-
parse_full(s)
308-
}
309-
310259
/// Convert a `Uri` from a static string.
311260
///
312261
/// This function will not perform any copying, however the string is
@@ -327,7 +276,7 @@ impl Uri {
327276
/// ```
328277
pub fn from_static(src: &'static str) -> Self {
329278
let s = Bytes::from_static(src.as_bytes());
330-
match Uri::from_shared(s) {
279+
match Uri::try_from(s) {
331280
Ok(uri) => uri,
332281
Err(e) => panic!("static str is not valid URI: {}", e),
333282
}
@@ -675,12 +624,86 @@ impl Uri {
675624
}
676625
}
677626

627+
impl TryFrom<Bytes> for Uri {
628+
type Error = InvalidUri;
629+
630+
/// Attempt to convert a `Uri` from `Bytes`
631+
///
632+
/// # Examples
633+
///
634+
/// ```
635+
/// # extern crate http;
636+
/// # use http::uri::*;
637+
/// extern crate bytes;
638+
///
639+
/// use std::convert::TryFrom;
640+
/// use bytes::Bytes;
641+
///
642+
/// # pub fn main() {
643+
/// let bytes = Bytes::from("http://example.com/foo");
644+
/// let uri = Uri::try_from(bytes).unwrap();
645+
///
646+
/// assert_eq!(uri.host().unwrap(), "example.com");
647+
/// assert_eq!(uri.path(), "/foo");
648+
/// # }
649+
/// ```
650+
fn try_from(s: Bytes) -> Result<Uri, Self::Error> {
651+
use self::ErrorKind::*;
652+
653+
if s.len() > MAX_LEN {
654+
return Err(TooLong.into());
655+
}
656+
657+
match s.len() {
658+
0 => {
659+
return Err(Empty.into());
660+
}
661+
1 => match s[0] {
662+
b'/' => {
663+
return Ok(Uri {
664+
scheme: Scheme::empty(),
665+
authority: Authority::empty(),
666+
path_and_query: PathAndQuery::slash(),
667+
});
668+
}
669+
b'*' => {
670+
return Ok(Uri {
671+
scheme: Scheme::empty(),
672+
authority: Authority::empty(),
673+
path_and_query: PathAndQuery::star(),
674+
});
675+
}
676+
_ => {
677+
let authority = Authority::try_from(s)?;
678+
679+
return Ok(Uri {
680+
scheme: Scheme::empty(),
681+
authority: authority,
682+
path_and_query: PathAndQuery::empty(),
683+
});
684+
}
685+
},
686+
_ => {}
687+
}
688+
689+
if s[0] == b'/' {
690+
return Ok(Uri {
691+
scheme: Scheme::empty(),
692+
authority: Authority::empty(),
693+
path_and_query: PathAndQuery::try_from(s)?,
694+
});
695+
}
696+
697+
parse_full(s)
698+
}
699+
}
700+
678701
impl<'a> TryFrom<&'a [u8]> for Uri {
679702
type Error = InvalidUri;
680703

681704
#[inline]
682705
fn try_from(t: &'a [u8]) -> Result<Self, Self::Error> {
683-
Uri::from_shared(Bytes::copy_from_slice(t))
706+
Uri::try_from(Bytes::copy_from_slice(t))
684707
}
685708
}
686709

@@ -707,7 +730,7 @@ impl TryFrom<String> for Uri {
707730

708731
#[inline]
709732
fn try_from(t: String) -> Result<Self, Self::Error> {
710-
Uri::from_shared(Bytes::from(t))
733+
Uri::try_from(Bytes::from(t))
711734
}
712735
}
713736

@@ -847,7 +870,7 @@ fn parse_full(mut s: Bytes) -> Result<Uri, InvalidUri> {
847870
Ok(Uri {
848871
scheme: scheme.into(),
849872
authority: authority,
850-
path_and_query: PathAndQuery::from_shared(s)?,
873+
path_and_query: PathAndQuery::try_from(s)?,
851874
})
852875
}
853876

0 commit comments

Comments
 (0)