6个版本 (3个重大更新)

0.4.1 2024年4月9日
0.4.0 2023年5月9日
0.3.0 2022年10月18日
0.2.0 2022年8月13日
0.1.1 2021年7月3日

#180 in 数据结构

Download history 90/week @ 2024-04-24 79/week @ 2024-05-01 25/week @ 2024-05-08 22/week @ 2024-05-15 23/week @ 2024-05-22 88/week @ 2024-05-29 71/week @ 2024-06-05 49/week @ 2024-06-12 56/week @ 2024-06-19 53/week @ 2024-06-26 41/week @ 2024-07-03 25/week @ 2024-07-10 44/week @ 2024-07-17 72/week @ 2024-07-24 430/week @ 2024-07-31 612/week @ 2024-08-07

1,166 每月下载量
用于 3 crates

MIT 许可证

29KB
439

validated

ResultEither 的累积兄弟。

Validated 类型具有特殊的 FromIterator 实例,这些实例能够报告序列中的所有错误,而不仅仅是第一个。

动机

我们可能会将 Iterator::collect 视为将某些链式迭代的结果合并到具体容器中,例如 Vec

let v = vec![1,2,3];
assert_eq!(vec![2,4,6], v.into_iter().map(|n| n * 2).collect::<Vec<u32>>());

collect 不限于这一点;只要它实现了 FromIterator,它就可以用于将结果“折叠”到任何你喜欢的类型中。考虑以下 impl 的效果 Result

let v: Vec<u32> = vec![1, 2, 3];
let r: Result<Vec<u32>, &str> = v
    .into_iter()
    .map(|n| if n % 2 == 0 { Err("Oh no!") } else { Ok(n * 2) })
    .collect();
assert_eq!(Err("Oh no!"), r);

Result 已经“交织”并拉回。关键的是,这个 collect 调用是短路;对于 3n * 2 从未调用,因为 map2 处“失败”。这在我们需要一系列IO操作都成功,并在任何错误发生时取消剩余操作时很有用。

但如果我们不想短路怎么办?如果我们想报告发生的所有错误怎么办?

累积错误和 Validated

考虑三种情况,我们希望报告所有错误,而不仅仅是第一个错误。

  1. 表单输入验证。
  2. 类型检查。
  3. 并发I/O。

在第一种情况下,如果用户犯了几个错误,最好一次性报告所有错误,以便他们可以在一次遍历中完成更正。

在第二种情况下,仅知道第一个检测到的类型错误可能实际上并不是问题的真正来源。我们需要报告所有故障,以便我们能够做出最好的修复决定。

在第三种情况下,在检测到单个故障时停止整个并发作业可能并不合适。您可能更希望所有作业都能完成,然后在结束时收集错误。

Validated 类型适用于这些用例;它是一个“累积的 Result”。

use validated::Validated::{self, Good, Fail};
use nonempty_collections::*;

let v = vec![Good(1), Validated::fail("No!"), Good(3), Validated::fail("Ack!")];
let r: Validated<Vec<u32>, &str> = Fail(nev!["No!", "Ack!"]);
assert_eq!(r, v.into_iter().collect());

非空向量(NEVec)的使用

本着“使非法状态无法表示”的精神,ValidatedFail 变体包含一个 NEVec,一个非空 VecNEVec 可以做所有 Vec 能做的事情,还有一些额外的优势。在这个 crate 中,这种表示禁止了其他情况下没有意义的 Fail(vec![])

换句话说,如果您有一个 Validated<T, E>,那么您要么有具体的 T,要么有至少一个 E

特性

  • rayon:为 Validated 启用 FromParallelIterator 实例。

资源

依赖关系

~150–415KB