We want to propose the usage of the effect clause to achieve operation genericity, for example:
#![allow(unused)]fnmain() {
traitRead {
fnread(&mutself, buf: &mut [u8]) -> Result<usize>
effect
async;
fnread_to_string(&mutself, buf: &mutString) -> Result<usize>
effect
async
{ .. }
}
/// Function to read from the file into a string which may exhibit async or const effectfnread_to_string(path: &str) -> io::Result<String>
effect
async, const
{
letmut string = String::new();
// We can be conditional over the context the function has been called from, // only when the function declaration has the `effect` clauseifasync || !async {
letmut file = File::open("foo.txt")?; // File implements Read// Because `read_to_string` is also an `effect` function that may or may not exhibit // async-ness par the declaration, we can use it on both contexts (async/sync) // we are placing the condition on.
file.read_to_string(&mut string)?; // .await will be inferred.
} else { // must be const// As the `read_to_string` doesn't exhibit const-ness, we'll need to handle it ourselves.
string = include_str!(path).to_string();
}
Ok(string)
}
/// A normal functionfnread() {
let data = read_to_string("hello.txt").unwrap();
}
/// A async functionasyncfnread() {
let data = read_to_string("hello.txt").await.unwrap();
}
/// A const functionconstfnread() {
let data = read_to_string("hello.txt").unwrap();
}
}
So in a nutshell, a function declaration with an effect clause is a special type of function that may or may not exhibit async or const behavior(effect) and it depends on the context of the function being called from and we can execute a different piece of code according to the context from the function was called from too (like the const_eval_select, resolves #6):
#![allow(unused)]fnmain() {
/// A trimmed-down version of the `std::Iterator` trait.pubtraitIterator {
typeItem;
fnnext(&mutself) -> Option<Self::Item>;
fnsize_hint(&self) -> (usize, Option<usize>);
}
/// An adaptation of `Iterator::find` to a free-functionpubfnfind<I, T, P>(iter: &mut I, predicate: P) -> Option<T>
where
I: Iterator<Item = T> + Sized,
P: FnMut(&T) -> bool;
}