From 1d0ae3dc292db84a315fc1bc917dc67716c9ccea Mon Sep 17 00:00:00 2001 From: Kamal Marhubi Date: Mon, 25 Jan 2016 22:18:08 -0500 Subject: [PATCH 1/2] core: Implement From for Option This allows improved ergonomics for functions that have optional parameters: instead of taking `Option`, they can have a type parameter bounded by `Into>`. That way, a value of type `T` can be passed directly without being wrapped by `Some`. As an example, a function fn foo(required: i32, optional: T) -> i32 where T: Into> { required + optional.into().unwrap_or(0) } can be called as `foo(2, None)` or as `foo(2, 3)`. Refs https://github.com/rust-lang/rfcs/issues/1402 --- src/libcore/option.rs | 9 +++++++++ src/libcoretest/option.rs | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 045c1f9feafc6..3a060feb87550 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -142,6 +142,7 @@ use self::Option::*; use clone::Clone; +use convert::From; use default::Default; use iter::ExactSizeIterator; use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator}; @@ -710,6 +711,14 @@ impl Default for Option { fn default() -> Option { None } } +#[unstable(feature = "option_from", reason = "recently added", issue = "0")] +impl From for Option { + #[inline] + fn from(t: T) -> Option { + Some(t) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl IntoIterator for Option { type Item = T; diff --git a/src/libcoretest/option.rs b/src/libcoretest/option.rs index 51b0655f680f6..93447556fe94f 100644 --- a/src/libcoretest/option.rs +++ b/src/libcoretest/option.rs @@ -270,3 +270,28 @@ fn test_cloned() { assert_eq!(opt_ref_ref.clone().cloned(), Some(&val)); assert_eq!(opt_ref_ref.cloned().cloned(), Some(1)); } + +#[test] +fn test_from() { + assert_eq!(Some(3), Option::from(3)); +} + +#[test] +fn test_into_optional_parameters() { + use core::convert::Into; + fn myfunc(t: T, u: U, v: V) -> Option + where T: Into>, + U: Into>, + V: Into> { + match (t.into() ,u.into(), v.into()) { + (Some(t), Some(u), Some(v)) => Some(t + u + v), + _ => None, + } + } + + assert_eq!(None, myfunc(None, 2, 3)); + assert_eq!(None, myfunc(1, None, 3)); + assert_eq!(None, myfunc(1, 2, None)); + assert_eq!(Some(6), myfunc(1, 2, 3)); + assert_eq!(Some(6), myfunc(Some(1), Some(2), Some(3))); +} From c7cd2751056edc35297cb176a88f34215bc23851 Mon Sep 17 00:00:00 2001 From: Kamal Marhubi Date: Sat, 23 Apr 2016 18:43:18 -0400 Subject: [PATCH 2/2] std::net: Use Into> for optional timeouts This allows writing code like stream.set_read_timeout(Duration::from_millis(200)); instead of requiring an additional `Some` wrapping the duration as is currently the case: stream.set_read_timeout(Some(Duration::from_millis(200))); --- src/libstd/net/tcp.rs | 18 ++++++++++-------- src/libstd/net/udp.rs | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 38da74b89039b..56e48bf10016c 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -136,8 +136,9 @@ impl TcpStream { /// a result of setting this option. For example Unix typically returns an /// error of the kind `WouldBlock`, but Windows may return `TimedOut`. #[stable(feature = "socket_timeout", since = "1.4.0")] - pub fn set_read_timeout(&self, dur: Option) -> io::Result<()> { - self.0.set_read_timeout(dur) + pub fn set_read_timeout(&self, dur: D) -> io::Result<()> + where D: Into> { + self.0.set_read_timeout(dur.into()) } /// Sets the write timeout to the timeout specified. @@ -152,8 +153,9 @@ impl TcpStream { /// as a result of setting this option. For example Unix typically returns /// an error of the kind `WouldBlock`, but Windows may return `TimedOut`. #[stable(feature = "socket_timeout", since = "1.4.0")] - pub fn set_write_timeout(&self, dur: Option) -> io::Result<()> { - self.0.set_write_timeout(dur) + pub fn set_write_timeout(&self, dur: D) -> io::Result<()> + where D: Into> { + self.0.set_write_timeout(dur.into()) } /// Returns the read timeout of this socket. @@ -1059,12 +1061,12 @@ mod tests { assert_eq!(None, t!(stream.read_timeout())); - t!(stream.set_read_timeout(Some(dur))); + t!(stream.set_read_timeout(dur)); assert_eq!(Some(dur), t!(stream.read_timeout())); assert_eq!(None, t!(stream.write_timeout())); - t!(stream.set_write_timeout(Some(dur))); + t!(stream.set_write_timeout(dur)); assert_eq!(Some(dur), t!(stream.write_timeout())); t!(stream.set_read_timeout(None)); @@ -1081,7 +1083,7 @@ mod tests { let listener = t!(TcpListener::bind(&addr)); let mut stream = t!(TcpStream::connect(&("localhost", addr.port()))); - t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + t!(stream.set_read_timeout(Duration::from_millis(1000))); let mut buf = [0; 10]; let start = Instant::now(); @@ -1097,7 +1099,7 @@ mod tests { let listener = t!(TcpListener::bind(&addr)); let mut stream = t!(TcpStream::connect(&("localhost", addr.port()))); - t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + t!(stream.set_read_timeout(Duration::from_millis(1000))); let mut other_end = t!(listener.accept()).0; t!(other_end.write_all(b"hello world")); diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 0be9f13e81761..e1230ab3b2d53 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -105,8 +105,9 @@ impl UdpSocket { /// a result of setting this option. For example Unix typically returns an /// error of the kind `WouldBlock`, but Windows may return `TimedOut`. #[stable(feature = "socket_timeout", since = "1.4.0")] - pub fn set_read_timeout(&self, dur: Option) -> io::Result<()> { - self.0.set_read_timeout(dur) + pub fn set_read_timeout(&self, dur: D) -> io::Result<()> + where D: Into> { + self.0.set_read_timeout(dur.into()) } /// Sets the write timeout to the timeout specified. @@ -121,8 +122,9 @@ impl UdpSocket { /// as a result of setting this option. For example Unix typically returns /// an error of the kind `WouldBlock`, but Windows may return `TimedOut`. #[stable(feature = "socket_timeout", since = "1.4.0")] - pub fn set_write_timeout(&self, dur: Option) -> io::Result<()> { - self.0.set_write_timeout(dur) + pub fn set_write_timeout(&self, dur: D) -> io::Result<()> + where D: Into> { + self.0.set_write_timeout(dur.into()) } /// Returns the read timeout of this socket. @@ -567,12 +569,12 @@ mod tests { assert_eq!(None, t!(stream.read_timeout())); - t!(stream.set_read_timeout(Some(dur))); + t!(stream.set_read_timeout(dur)); assert_eq!(Some(dur), t!(stream.read_timeout())); assert_eq!(None, t!(stream.write_timeout())); - t!(stream.set_write_timeout(Some(dur))); + t!(stream.set_write_timeout(dur)); assert_eq!(Some(dur), t!(stream.write_timeout())); t!(stream.set_read_timeout(None)); @@ -587,7 +589,7 @@ mod tests { let addr = next_test_ip4(); let stream = t!(UdpSocket::bind(&addr)); - t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + t!(stream.set_read_timeout(Duration::from_millis(1000))); let mut buf = [0; 10]; @@ -602,7 +604,7 @@ mod tests { let addr = next_test_ip4(); let stream = t!(UdpSocket::bind(&addr)); - t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + t!(stream.set_read_timeout(Duration::from_millis(1000))); t!(stream.send_to(b"hello world", &addr));