New idiom: return moved arg on error (#336)

Co-authored-by: Julian Ganz <neither@nut.email>
Co-authored-by: Marco Ieni <11428655+MarcoIeni@users.noreply.github.com>
pull/342/head
Mikhail Trishchenkov 1 year ago committed by GitHub
parent 7580985e8b
commit 87373fa34d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -20,6 +20,7 @@
- [Privacy For Extensibility](./idioms/priv-extend.md)
- [Easy doc initialization](./idioms/rustdoc-init.md)
- [Temporary mutability](./idioms/temporary-mutability.md)
- [Return consumed arg on error](./idioms/return-consumed-arg-on-error.md)
- [Design Patterns](./patterns/index.md)
- [Behavioural](./patterns/behavioural/intro.md)

@ -0,0 +1,61 @@
# Return consumed argument on error
## Description
If a fallible function consumes (moves) an argument, return that argument back inside
an error.
## Example
```rust
pub fn send(value: String) -> Result<(), SendError> {
println!("using {value} in a meaningful way");
// Simulate non-deterministic fallible action.
use std::time::SystemTime;
let period = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
if period.subsec_nanos() % 2 == 1 {
Ok(())
} else {
Err(SendError(value))
}
}
pub struct SendError(String);
fn main() {
let mut value = "imagine this is very long string".to_string();
let success = 'send: {
// Try to send value two times.
for _ in 0..2 {
value = match send(value) {
Ok(()) => break 'send true,
Err(SendError(value)) => value,
}
}
false
};
println!("success: {}", success);
}
```
## Motivation
In case of error you may want to try some alternative way or to
retry action in case of non-deterministic function. But if the argument
is always consumed, you are forced to clone it on every call, which
is not very efficient.
The standard library uses this approach in e.g. `String::from_utf8` method.
When given a vector that doesn't contain valid UTF-8, a `FromUtf8Error`
is returned.
You can get original vector back using `FromUtf8Error::into_bytes` method.
## Advantages
Better performance because of moving arguments whenever possible.
## Disadvantages
Slightly more complex error types.
Loading…
Cancel
Save