#traits #off #anything #chain #collection #self #deref-mut

ov

一组允许您从任何事物中链式调用的特性

2个不稳定版本

0.1.0 2020年10月18日
0.0.1 2020年10月13日

#1811 in 数据结构

MIT 许可证

9KB
62

ov

'ov' 包提供了一组特性,允许您从任何事物中链式调用。每个特性都有一个与特性同名的单个方法(但以蛇形命名)。

OverOverRefOverMut 分别对应于 self&self&mut self,回调接收相同的值。它们适用于所有类型。

OverDerefOverDerefMut 为具有 DerefDerefMut 实现的类型实现。它们都借用接收者,并将 Deref::target 的引用传递给回调。

使用方法

您可以通配符导入它,也可以导入特定的特性。在 semver 兼容版本中不会添加新项目。

use ov::*;

或者

use ov::Over;

示例

这种用法通常与一元枚举或结构体构造函数一起使用。否则,这些将是带有变量的多个语句或嵌套括号。

use ov::*;
use std::error::Error;
use std::io::{Error as IoError, ErrorKind};

fn maybe_string() -> Option<String> {
    "foo".to_owned().over(Some)
}
assert_eq!(maybe_string(), Some("foo".to_owned()));

// A helper is needed as `.over(Box::new)` always creates a Box<IoError>
fn to_err_object(error: impl Error + Send + 'static) -> Box<dyn Error + Send> {
    Box::new(error)
}

fn try_io_thing() -> Result<(), Box<dyn Error + Send>> {
    IoError::new(ErrorKind::Other, "oh no!").over(to_err_object).over(Err)
}

可以使用 .over_mut 方法对任意值执行一些修改,包括结构体的字段。

use ov::*;
struct S { field: i32 }
let mut s = S { field: 5 };

s.field.over_mut(|n| {
    // n is &mut i32
    *n *= 3;
    *n += 1;
});
assert_eq!(s.field, 16);

如果您想使用一个接受例如 &str 的函数,并且您有一个 String,则 over_derefover_deref_mut 方法非常有用。

let s = String::from("Hello, world!");
// Note: this would fail if `my_str` were `String` or `&String`
let len = s.over_deref(|my_str| str::len(my_str));
// Can be shortened to this
let len = s.over_deref(str::len);
assert_eq!(len, 13);

这种情况的另一个例子是从可变引用中提取值。为此,我们可以使用 std::mem::takestd::mem::replace。在下面的示例中,我们必须使用 replace,因为 Command 没有实现 Default

use std::process::Command;
fn assert_type<T>(_x: T) {}

let command = Command::new("ls")
    .arg("-a") // returns &mut Command
    .arg("-l") // returns &mut Command
    .over(|r| std::mem::replace(r, Command::new(""))); // returns Command

assert_type::<Command>(command);

License: MIT

无运行时依赖