Skip to content

Commit 47f4584

Browse files
committed
feature: make possible to set port number in Uri::builder
1 parent 59733e1 commit 47f4584

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

src/uri/builder.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
use std::convert::{TryFrom, TryInto};
1+
use std::{
2+
convert::{TryFrom, TryInto},
3+
fmt::Write,
4+
};
25

3-
use super::{Authority, Parts, PathAndQuery, Scheme};
4-
use crate::Uri;
6+
use super::{port::Port, Authority, ErrorKind, InvalidUriParts, Parts, PathAndQuery, Scheme};
7+
use crate::{byte_str::ByteStr, Uri};
58

69
/// A builder for `Uri`s.
710
///
@@ -78,6 +81,39 @@ impl Builder {
7881
})
7982
}
8083

84+
/// Set the port number for URI, will be part of `Authority`
85+
pub fn port<T, P>(self, port: P) -> Self
86+
where
87+
P: Into<Port<T>>,
88+
{
89+
let port: Port<T> = port.into();
90+
self.port_u16(port.as_u16())
91+
}
92+
93+
/// Set the port number for URI, will be part of `Authority`
94+
pub fn port_u16(self, port: u16) -> Self {
95+
self.map(move |mut parts| {
96+
let prev_auth = match parts.authority.as_ref() {
97+
Some(auth) => {
98+
if auth.port().is_some() {
99+
return Err(InvalidUriParts::from(ErrorKind::InvalidPort).into());
100+
}
101+
102+
auth.as_str()
103+
}
104+
None => "",
105+
};
106+
// 1 for ':', 5 for port number digists
107+
let mut auth = String::with_capacity(prev_auth.len() + 6);
108+
auth.push_str(prev_auth);
109+
auth.push(':');
110+
write!(&mut auth, "{}", port).expect("write to String failed");
111+
let data: ByteStr = auth.into();
112+
parts.authority = Some(Authority { data });
113+
Ok(parts)
114+
})
115+
}
116+
81117
/// Set the `PathAndQuery` for this URI.
82118
///
83119
/// # Examples

src/uri/tests.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,3 +517,34 @@ fn test_partial_eq_path_with_terminating_questionmark() {
517517

518518
assert_eq!(uri, a);
519519
}
520+
521+
#[test]
522+
fn test_uri_builder() {
523+
assert_eq!(
524+
"ws://localhost:8000/demo/",
525+
Uri::builder()
526+
.scheme("ws")
527+
.authority("localhost")
528+
.port_u16(8000)
529+
.path_and_query("/demo/")
530+
.build()
531+
.unwrap()
532+
);
533+
assert_eq!(
534+
"ws://[2001:db8:1f70::999:de8:7648:6e8]:8000/demo/",
535+
Uri::builder()
536+
.scheme("ws")
537+
.authority("[2001:db8:1f70::999:de8:7648:6e8]")
538+
.port_u16(8000)
539+
.path_and_query("/demo/")
540+
.build()
541+
.unwrap()
542+
);
543+
Uri::builder()
544+
.scheme("ws")
545+
.authority("localhost:8000")
546+
.port_u16(8000)
547+
.path_and_query("/demo/")
548+
.build()
549+
.unwrap_err();
550+
}

0 commit comments

Comments
 (0)