From 6193dd8c4b1357d106073868d9a0aebc2d6c13dc Mon Sep 17 00:00:00 2001 From: benaryorg Date: Sat, 4 Jun 2016 22:58:21 +0200 Subject: [PATCH 1/3] add: duration_checked_sub RFC Signed-off-by: benaryorg --- text/0000-duration-checked-sub.md | 93 +++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 text/0000-duration-checked-sub.md diff --git a/text/0000-duration-checked-sub.md b/text/0000-duration-checked-sub.md new file mode 100644 index 00000000000..21e55430f81 --- /dev/null +++ b/text/0000-duration-checked-sub.md @@ -0,0 +1,93 @@ +- Feature Name: duration_checked_sub +- Start Date: 2016-06-04 +- RFC PR: +- Rust Issue: + +# Summary +[summary]: #summary + +This RFC adds `checked_sub()` already known from various primitive types to the +`Duration` *struct*. + +# Motivation +[motivation]: #motivation + +Generally this helps when subtracting `Duration`s which can be the case quite +often. + +One abstract example would be executing a specific piece of code repeatedly +after a constant amount of time. + +Specific examples would be a network service or a rendering process emitting a +constant amount of frames per second. + +Example code would be as follows: + +```rust + +// This function is called repeatedly +fn render() { + // 10ms delay results in 100 frames per second + let wait_time = Duration::from_millis(10); + + // `Instant` for elapsed time + let start = Instant::now(); + + // execute code here + render_and_output_frame(); + + // there are no negative `Duration`s so this does nothing if the elapsed + // time is longer than the defined `wait_time` + start.elapsed().checked_sub(wait_time).and_then(std::thread::sleep); +} +``` + +# Detailed design +[design]: #detailed-design + +The detailed design would be exactly as the current `sub()` method, just +returning an `Option` and passing possible `None` values from the +underlying primitive types: + +```rust +impl Duration { + fn checked_sub(self, rhs: Duration) -> Duration { + if let Some(mut secs) = self.secs.checked_sub(rhs.secs) { + let nanos = if self.nanos >= rhs.nanos { + self.nanos - rhs.nanos + } else { + if let Some(secs) = secs.checked_sub(1) { + self.nanos + NANOS_PER_SEC - rhs.nanos + } + else { + return None; + } + }; + debug_assert!(nanos < NANOS_PER_SEC); + Duration { secs: secs, nanos: nanos } + } + else { + None + } + } +} +``` + +# Drawbacks +[drawbacks]: #drawbacks + +This proposal adds another `checked_*` method to *libstd*. +One could ask why no `CheckedSub` trait if there is a `Sub` trait. + +# Alternatives +[alternatives]: #alternatives + +The alternatives are simply not doing this and forcing the programmer to code +the check on their behalf. + +# Unresolved questions +[unresolved]: #unresolved-questions + +Should all functions of the form +`(checked|saturating|overflowing|wrapping)_(add|sub|mul|div)` be added? + From 39aff7ca15ccece79e60c7008a4eb38cda598c93 Mon Sep 17 00:00:00 2001 From: benaryorg Date: Thu, 11 Aug 2016 23:31:38 +0200 Subject: [PATCH 2/3] add: list of methods to be implemented as of current state of discussion Signed-off-by: benaryorg --- text/0000-duration-checked-sub.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/text/0000-duration-checked-sub.md b/text/0000-duration-checked-sub.md index 21e55430f81..5edca47239e 100644 --- a/text/0000-duration-checked-sub.md +++ b/text/0000-duration-checked-sub.md @@ -6,8 +6,8 @@ # Summary [summary]: #summary -This RFC adds `checked_sub()` already known from various primitive types to the -`Duration` *struct*. +This RFC adds the `checked_*` methods already known from primitives like +`usize` to `Duration`. # Motivation [motivation]: #motivation @@ -42,6 +42,9 @@ fn render() { } ``` +Of course it is also suitable to not introduce `panic!()`s when adding +`Duration`s. + # Detailed design [design]: #detailed-design @@ -73,21 +76,27 @@ impl Duration { } ``` +The same accounts for all other added methods, namely: + +- `checked_add()` +- `checked_sub()` +- `checked_mul()` +- `checked_div()` + # Drawbacks [drawbacks]: #drawbacks -This proposal adds another `checked_*` method to *libstd*. -One could ask why no `CheckedSub` trait if there is a `Sub` trait. +`None`. # Alternatives [alternatives]: #alternatives The alternatives are simply not doing this and forcing the programmer to code the check on their behalf. +This is not what you want. # Unresolved questions [unresolved]: #unresolved-questions -Should all functions of the form -`(checked|saturating|overflowing|wrapping)_(add|sub|mul|div)` be added? +`None`. From bde7d918cd9ce816a2b25792b88cdb2c71f8e65f Mon Sep 17 00:00:00 2001 From: benaryorg Date: Wed, 17 Aug 2016 00:41:54 +0200 Subject: [PATCH 3/3] fix code for method Signed-off-by: benaryorg --- text/0000-duration-checked-sub.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-duration-checked-sub.md b/text/0000-duration-checked-sub.md index 5edca47239e..2ce627b1b9b 100644 --- a/text/0000-duration-checked-sub.md +++ b/text/0000-duration-checked-sub.md @@ -54,7 +54,7 @@ underlying primitive types: ```rust impl Duration { - fn checked_sub(self, rhs: Duration) -> Duration { + fn checked_sub(self, rhs: Duration) -> Option { if let Some(mut secs) = self.secs.checked_sub(rhs.secs) { let nanos = if self.nanos >= rhs.nanos { self.nanos - rhs.nanos @@ -67,7 +67,7 @@ impl Duration { } }; debug_assert!(nanos < NANOS_PER_SEC); - Duration { secs: secs, nanos: nanos } + Some(Duration { secs: secs, nanos: nanos }) } else { None