|
1 | | -use std::convert::{TryFrom, TryInto}; |
| 1 | +use std::{ |
| 2 | + convert::{TryFrom, TryInto}, |
| 3 | + fmt::Write, |
| 4 | +}; |
2 | 5 |
|
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}; |
5 | 8 |
|
6 | 9 | /// A builder for `Uri`s. |
7 | 10 | /// |
@@ -78,6 +81,39 @@ impl Builder { |
78 | 81 | }) |
79 | 82 | } |
80 | 83 |
|
| 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 | + |
81 | 117 | /// Set the `PathAndQuery` for this URI. |
82 | 118 | /// |
83 | 119 | /// # Examples |
|
0 commit comments