Created
August 5, 2021 23:06
-
-
Save AnthonyMikh/58d6cd2e967f5b12ff615d169024fb2f to your computer and use it in GitHub Desktop.
Automatic cleanup of resources wuth a specified operation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct AutoDo<T, F> { | |
value: T, | |
action: F, | |
} | |
struct DoOnDrop<'a, T, F: FnMut(&mut T)>(&'a mut AutoDo<T, F>); | |
impl<T, F> AutoDo<T, F> { | |
fn new(value: T, action: F) -> Self { | |
Self { value, action } | |
} | |
fn get(&mut self) -> DoOnDrop<'_, T, F> | |
where | |
F: for<'a> FnMut(&'a mut T), | |
{ | |
DoOnDrop(self) | |
} | |
fn into_inner(self) -> T { | |
self.value | |
} | |
} | |
impl<'a, T, F: FnMut(&mut T)> Drop for DoOnDrop<'a, T, F> { | |
fn drop(&mut self) { | |
(self.0.action)(&mut self.0.value) | |
} | |
} | |
impl<'a, T, F: FnMut(&mut T)> std::ops::Deref for DoOnDrop<'a, T, F> { | |
type Target = T; | |
fn deref(&self) -> &T { | |
&self.0.value | |
} | |
} | |
impl<'a, T, F: FnMut(&mut T)> std::ops::DerefMut for DoOnDrop<'a, T, F> { | |
fn deref_mut(&mut self) -> &mut T { | |
&mut self.0.value | |
} | |
} | |
fn main() { | |
use std::io::Read; | |
let stdin = std::io::stdin(); | |
let mut stdin = stdin.lock(); | |
let mut buf = AutoDo::new(String::new(), String::clear); | |
loop { | |
let mut buf = buf.get(); | |
if let Ok(0) | Err(_) = stdin.read_to_string(&mut buf) { | |
break; | |
} | |
if buf.contains("nope") { | |
continue; // работает и с continue | |
} | |
println!("{}", buf.to_uppercase()); | |
} | |
let buf = buf.into_inner(); | |
assert!(buf.is_empty()); // буфер в итоге пустой | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment