#derive #from-str #iterator #vec #vector

collections-fromstr

为 Vec 或 HashSet 等集合类型派生 FromStr

2 个版本

0.1.1 2021 年 5 月 14 日
0.1.0 2021 年 5 月 14 日

#301解析工具

每月 36 次下载

MIT/Apache

19KB
272 代码行

collections-fromstr

此软件包提供对单类型可迭代集合上的新类型的 FromStr 派生的支持,例如 Vec<T>HashSet<T>。通过您通过 #[item_separator] 属性指定的模式拆分输入来解析元素。然后使用各自的 FromStr 实现解析单独的项目。

要求

  • 该宏将取您结构体中第一个具有路径参数类型 <T> 的字段,并假定它是内部类型。它将假定此示例中的 T 是项目类型。
  • 项目类型 T 不能是实际类型(没有特质类型)且实现了 FromStr
  • 作为内部类型,您可以使用任何实现 FromIterator<Item = T>(如 Vec<T>HashSet<T>)的类型。
  • From 需要在您的新类型及其内部类型之间实现。像 derive_more 这样的软件包可以轻松处理这个问题。

示例

use collections_fromstr::FromStr;
use derive_more::From;
use std::str::FromStr;

#[derive(From, FromStr, PartialEq)]
#[item_separator = ","]
struct NewVec(Vec<i32>);

static VALUES: &str = "1,2,3,-3,-2,-1";
assert!(
    NewVec::from_str(VALUES).unwrap() == NewVec(vec![1,2,3,-3,-2,-1])
);

等等...你知道我可以直接使用 Iterator::split 来做这件事,对吧?

好吧,听我说。假设你有这样的数据

1-3:B,I,U//43-60:I//83-87:I,U//99-104: B,I// [etc.]

假设这些数据代表文本标记:冒号左侧是字符范围:,右侧是高亮信息(B=加粗,I=斜体,U=下划线,但一旦你有了对冲基金的钱,你可能还会扩展它),可能有多个,用逗号,分隔。每个标记之间用双斜杠//分隔。

... 现在看看FromStr的魔法效果

use std::collections::HashSet;
use derive_more::From;
use std::ops::Range;

#[derive(parse_display::FromStr)]
#[display("{0.start}-{0.end}")]
struct CharRange(#[from_str(default)] Range<u32>);

#[derive(parse_display::FromStr, Hash, PartialEq, Eq)]
#[non_exhaustive]
enum MarkupOperation {
    #[display("B")]
    Bold,
    #[display("I")]
    Italics, 
    #[display("U")]
    Underline,
}

#[derive(From, collections_fromstr::FromStr)]
#[item_separator=","]
struct Operations(HashSet<MarkupOperation>);

#[derive(parse_display::FromStr)]
#[display("{range}:{operations}")]
struct Markup{
    range: CharRange,
    operations: Operations,
}

#[derive(From, collections_fromstr::FromStr)]
#[item_separator="//"]
struct MarkupVec(Vec<Markup>);

看看这段代码。真是太干净了。🥺 你也不太可能产生像忘记空输入字符串的情况这样的错误。

许可证

collections-fromstr在MIT许可证和Apache许可证(版本2.0)的条款下分发。

有关详细信息,请参阅LICENSE-APACHELICENSE-MIT

依赖项

约1.5MB
约33K SLoC