#macro-derive #functor #derive #proc-macro #data-structures

functor_derive

为类型派生函数式对象的宏

10 个不稳定版本 (3 个破坏性更改)

0.4.3 2024年4月12日
0.4.2 2023年12月11日
0.3.2 2023年12月9日
0.2.3 2023年10月31日
0.0.2 2023年10月28日

Rust 模式404

Download history 2/week @ 2024-04-20 1/week @ 2024-05-18 7/week @ 2024-06-01 1/week @ 2024-06-08 1/week @ 2024-06-22 15/week @ 2024-06-29 1/week @ 2024-07-06 21/week @ 2024-07-20 31/week @ 2024-07-27

每月下载量 52

MIT 许可证

29KB
599 代码行

Functor Derive

githubcrates-iodocs-rs

此包可以为泛型结构体和枚举生成函数式对象。

函数式对象是一个包含 fmap 函数的特质,它将泛型参数进行映射。这允许你在不改变其形状的情况下转换任何类型的内容。

以下示例演示了如何派生函数式对象,为你提供了一个 fmap 方法。对于更复杂的示例,请参阅项目仓库中的测试目录 (项目仓库测试目录)

use functor_derive::Functor;

#[derive(Functor)]
struct MyType<T> {
    value: T,
    list: Vec<T>,
    unaffected: bool,
}

fn main() {
    let original = MyType { value: 42, list: vec![1, 3], unaffected: false };
    let transformed = original.fmap(|x| (x, x * 2));

    assert_eq!(transformed.value, (42, 84));
    assert_eq!(transformed.list, vec![(1, 2), (3, 6)]);
}

此外,还生成了一个 try_fmap 函数,这在进行可能失败的操作时很有用。

let original = MyType { value: "42", list: vec!["1", "3"], unaffected: false };
let transformed = original.try_fmap(|x| x.parse::<u64>())?;

属性

你可以通过多种方式调用派生宏。省略属性默认为为第一个泛型类型参数派生 Functor 特质,如上述第一个示例所示。

或者,你可以指定一个默认类型来覆盖派生宏,这将阻止派生宏选择第一个泛型类型参数。这可以通过以下方式完成

#[derive(Functor)]
#[functor(T2)]
struct MyType<T1, T2> {
    field_1: T1,
    field_2: T2,
}

有时,你可能想要使用 as 关键字重命名 fmap 函数。以下示例生成了方法 fmap_keys

#[derive(Functor)]
#[functor(K as keys)]
struct MyType<K> {
    keys: Vec<K>
}

以上选项可以通过逗号分隔组合生成多个实现。下面的代码生成了 3 个方法:fmapfmap_keysfmap_values

use std::collections::HashMap;
use std::hash::Hash;

#[functor(V, K as keys, V as values)]
struct MyHashMap<K: Hash + Eq, V> {
    v: HashMap<K, V>
}

支持的功能

此包可以完美处理以下内容

  • 结构体 - 除了单元结构体,它不能是泛型的
  • 枚举
  • 数组
  • 元组
  • std::collections: Vec, VecDeque, LinkedList, HashSet, HashMap, BTreeMap, Result, Option, PhantomData
  • 嵌套类型,例如 Option<Box<T>>
  • (互)递归类型
  • 有界参数,例如 T: Display

如果您发现 derive 宏失败的情况,请随时在此处创建一个 issue

依赖项

~0.8–1.2MB
~27K SLoC