2个版本

0.1.1 2024年5月20日
0.1.0 2024年5月2日

#969算法

每月21次下载
diazene 中使用

MIT 许可证

9KB
97

AnyId (p_-)

此库提供 anyid::AnyId 结构体,可以作为HashMap键等的标识符使用,同时保持类型信息模糊。


为什么需要这个功能?

所有数据通常都有一个标识符来识别它。它通常被类型严格约束。(例如,使用类似于 ProductId(uuid::Uuid) 的新类型模式,而不是仅仅使用 uuid::Uuid)。然而,当这些数据被合并在一起并以整体的方式处理时,这些类型限制似乎有些繁琐。因此,我们可以通过提供一个使用Trait的TraitObject来解决此问题,该Trait是作为标识符使用时至少要实现的Trait集合。请注意,此crate旨在促进应用层面的数据处理,而不是用于忽略类型处理(如序列化和反序列化)。另外,如果您使用此crate作为数据的标识符,将来可能会非常麻烦,因为它仅实现了组织化处理数据所需的功能。

详细信息

内部结构

anyid::AnyId 在内部使用 Identifier Trait,并将其包装在 Arc<T> 中作为trait-object。

pub struct AnyId(Arc<dyn Identifier>);

特质约束

具有多个Trait实现的结构的Trait Identifier 会自动实现。

  • 可复制
    • 为什么需要这个:当存在需要 'static 生命周期的范围时,例如在 tokio::spawn 或将数据插入 HashMap 等情况下,数据通常会被复制,因为它消耗值并且可以被反复使用。在大多数情况下,使用的是复制的数据。此外,我们认为使用 Copy 比使用 Clone 更合适,因为标识符应该是“复制时资源消耗更少”。
  • PartialEq/Eq
  • Display/Debug
  • Sync/Send
  • Hash

用法

构建

anyid::AnyId 提供了类似于通用结构的新功能,参数需要一个 impl Identifier

use anyid::AnyId;

fn main() {
    let str_id: &str = "abc123";
    let id = AnyId::new(str_id);
}

此外,如果满足 Identifier 的默认实现条件,将自动提供 From 实现。

use anyid::AnyId;

fn main() {
  let str_id: &str = "abc123";
  let id: AnyId = str_id.into();
}

克隆

anyid::AnyId 本身不提供 Copy
然而,它使用 Arc::clone 实现了 Clone

impl Clone for AnyId {
  fn clone(&self) -> Self {
    Self(Arc::clone(&self.0))
  }
}

因此,Clone 的成本更低。

相等

Eq/(PartialEq) 的实现位于 Identifier 中。

fn eq(&self, other: &dyn Identifier) -> bool {
  let Some(other) = other.as_any().downcast_ref::<T>() else {
    return false;
  };

  self.eq(other)
}

这个过程很简单,但重要的是要注意,这个过程不使用 Result<T, E>。如果向下转型失败,将返回 false。


许可

此库在 MIT 许可下发布。
欢迎提出错误报告和改进意见;D。

依赖项

~12KB