Skip to content

Commit 8bb4b5f

Browse files
committed
Support parsing IP addresses from a byte string
1 parent 983f4da commit 8bb4b5f

File tree

1 file changed

+125
-13
lines changed

1 file changed

+125
-13
lines changed

library/std/src/net/parser.rs

+125-13
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ struct Parser<'a> {
3939
}
4040

4141
impl<'a> Parser<'a> {
42-
fn new(input: &'a str) -> Parser<'a> {
43-
Parser { state: input.as_bytes() }
42+
fn new(input: &'a [u8]) -> Parser<'a> {
43+
Parser { state: input }
4444
}
4545

4646
/// Run a parser, and restore the pre-parse state if it fails.
@@ -273,56 +273,168 @@ impl<'a> Parser<'a> {
273273
}
274274
}
275275

276+
impl IpAddr {
277+
/// Parse an IP address from a slice of bytes.
278+
///
279+
/// ```
280+
/// #![feature(addr_parse_ascii)]
281+
///
282+
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
283+
///
284+
/// let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
285+
/// let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
286+
///
287+
/// assert_eq!(IpAddr::parse_ascii(b"127.0.0.1"), Ok(localhost_v4));
288+
/// assert_eq!(IpAddr::parse_ascii(b"::1"), Ok(localhost_v6));
289+
/// ```
290+
#[unstable(feature = "addr_parse_ascii", issue = "101035")]
291+
pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
292+
Parser::new(b).parse_with(|p| p.read_ip_addr(), AddrKind::Ip)
293+
}
294+
}
295+
276296
#[stable(feature = "ip_addr", since = "1.7.0")]
277297
impl FromStr for IpAddr {
278298
type Err = AddrParseError;
279299
fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
280-
Parser::new(s).parse_with(|p| p.read_ip_addr(), AddrKind::Ip)
300+
Self::parse_ascii(s.as_bytes())
281301
}
282302
}
283303

284-
#[stable(feature = "rust1", since = "1.0.0")]
285-
impl FromStr for Ipv4Addr {
286-
type Err = AddrParseError;
287-
fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
304+
impl Ipv4Addr {
305+
/// Parse an IPv4 address from a slice of bytes.
306+
///
307+
/// ```
308+
/// #![feature(addr_parse_ascii)]
309+
///
310+
/// use std::net::Ipv4Addr;
311+
///
312+
/// let localhost = Ipv4Addr::new(127, 0, 0, 1);
313+
///
314+
/// assert_eq!(Ipv4Addr::parse_ascii(b"127.0.0.1"), Ok(localhost));
315+
/// ```
316+
#[unstable(feature = "addr_parse_ascii", issue = "101035")]
317+
pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
288318
// don't try to parse if too long
289-
if s.len() > 15 {
319+
if b.len() > 15 {
290320
Err(AddrParseError(AddrKind::Ipv4))
291321
} else {
292-
Parser::new(s).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4)
322+
Parser::new(b).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4)
293323
}
294324
}
295325
}
296326

327+
#[stable(feature = "rust1", since = "1.0.0")]
328+
impl FromStr for Ipv4Addr {
329+
type Err = AddrParseError;
330+
fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
331+
Self::parse_ascii(s.as_bytes())
332+
}
333+
}
334+
335+
impl Ipv6Addr {
336+
/// Parse an IPv6 address from a slice of bytes.
337+
///
338+
/// ```
339+
/// #![feature(addr_parse_ascii)]
340+
///
341+
/// use std::net::Ipv6Addr;
342+
///
343+
/// let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
344+
///
345+
/// assert_eq!(Ipv6Addr::parse_ascii(b"::1"), Ok(localhost));
346+
/// ```
347+
#[unstable(feature = "addr_parse_ascii", issue = "101035")]
348+
pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
349+
Parser::new(b).parse_with(|p| p.read_ipv6_addr(), AddrKind::Ipv6)
350+
}
351+
}
352+
297353
#[stable(feature = "rust1", since = "1.0.0")]
298354
impl FromStr for Ipv6Addr {
299355
type Err = AddrParseError;
300356
fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
301-
Parser::new(s).parse_with(|p| p.read_ipv6_addr(), AddrKind::Ipv6)
357+
Self::parse_ascii(s.as_bytes())
358+
}
359+
}
360+
361+
impl SocketAddrV4 {
362+
/// Parse an IPv4 socket address from a slice of bytes.
363+
///
364+
/// ```
365+
/// #![feature(addr_parse_ascii)]
366+
///
367+
/// use std::net::{Ipv4Addr, SocketAddrV4};
368+
///
369+
/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
370+
///
371+
/// assert_eq!(SocketAddrV4::parse_ascii(b"127.0.0.1:8080"), Ok(socket));
372+
/// ```
373+
#[unstable(feature = "addr_parse_ascii", issue = "101035")]
374+
pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
375+
Parser::new(b).parse_with(|p| p.read_socket_addr_v4(), AddrKind::SocketV4)
302376
}
303377
}
304378

305379
#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
306380
impl FromStr for SocketAddrV4 {
307381
type Err = AddrParseError;
308382
fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
309-
Parser::new(s).parse_with(|p| p.read_socket_addr_v4(), AddrKind::SocketV4)
383+
Self::parse_ascii(s.as_bytes())
384+
}
385+
}
386+
387+
impl SocketAddrV6 {
388+
/// Parse an IPv6 socket address from a slice of bytes.
389+
///
390+
/// ```
391+
/// #![feature(addr_parse_ascii)]
392+
///
393+
/// use std::net::{Ipv6Addr, SocketAddrV6};
394+
///
395+
/// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
396+
///
397+
/// assert_eq!(SocketAddrV6::parse_ascii(b"[2001:db8::1]:8080"), Ok(socket));
398+
/// ```
399+
#[unstable(feature = "addr_parse_ascii", issue = "101035")]
400+
pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
401+
Parser::new(b).parse_with(|p| p.read_socket_addr_v6(), AddrKind::SocketV6)
310402
}
311403
}
312404

313405
#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
314406
impl FromStr for SocketAddrV6 {
315407
type Err = AddrParseError;
316408
fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
317-
Parser::new(s).parse_with(|p| p.read_socket_addr_v6(), AddrKind::SocketV6)
409+
Self::parse_ascii(s.as_bytes())
410+
}
411+
}
412+
413+
impl SocketAddr {
414+
/// Parse a socket address from a slice of bytes.
415+
///
416+
/// ```
417+
/// #![feature(addr_parse_ascii)]
418+
///
419+
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
420+
///
421+
/// let socket_v4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
422+
/// let socket_v6 = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8080);
423+
///
424+
/// assert_eq!(SocketAddr::parse_ascii(b"127.0.0.1:8080"), Ok(socket_v4));
425+
/// assert_eq!(SocketAddr::parse_ascii(b"[::1]:8080"), Ok(socket_v6));
426+
/// ```
427+
#[unstable(feature = "addr_parse_ascii", issue = "101035")]
428+
pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
429+
Parser::new(b).parse_with(|p| p.read_socket_addr(), AddrKind::Socket)
318430
}
319431
}
320432

321433
#[stable(feature = "rust1", since = "1.0.0")]
322434
impl FromStr for SocketAddr {
323435
type Err = AddrParseError;
324436
fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
325-
Parser::new(s).parse_with(|p| p.read_socket_addr(), AddrKind::Socket)
437+
Self::parse_ascii(s.as_bytes())
326438
}
327439
}
328440

0 commit comments

Comments
 (0)