#owned #derive #no-std #into-owned

no-std ownable

用于具有 Cow 的结构体/枚举的派生宏,可以将 Type<'a> 转换为 Type<'static> 以及更多功能

4 个版本

0.6.2 2024 年 2 月 4 日
0.6.1 2023 年 9 月 20 日
0.6.0 2023 年 5 月 6 日
0.5.0 2023 年 4 月 12 日

Rust 模式 中排名 #418

Download history 1/week @ 2024-04-29 23/week @ 2024-05-06 30/week @ 2024-05-13 142/week @ 2024-05-20 137/week @ 2024-05-27 99/week @ 2024-06-03 98/week @ 2024-06-10 172/week @ 2024-06-17 122/week @ 2024-06-24 208/week @ 2024-07-01 109/week @ 2024-07-08 157/week @ 2024-07-15 186/week @ 2024-07-22 198/week @ 2024-07-29 124/week @ 2024-08-05 103/week @ 2024-08-12

每月下载量 637
6 个 crate 中使用(通过 rc-zip

MIT/Apache 许可

37KB
656 行(不含注释)

Dependency status crates.io Downloads Github stars License

crate ownable

用于具有 Cow 的结构体/枚举的派生宏

自动将 Type<'a> 转换为 Type<'static> 以及更多。

示例

这对于使用 serde 借用的类型非常有帮助。

#[derive(IntoOwned, ToBorrowed, ToOwned)]
// #[derive(serde::Serialize, serde::Deserialize)]
pub struct Type<'a> {
  // #[serde(borrow)]
  cow: Cow<'a, str>,
  #[ownable(clone)] owned: String, // always clone this field
}

将派生类似于以下功能

impl Type<'_> {
  /// Copy the structure and clone the original values if it's not owned.
  /// This is always a deep copy of the structure.
  pub fn into_owned(self) -> Type<'static> {
    Type {
      cow: Cow::Owned(Cow::into_owned(self.cow)),
      owned: self.owned.clone(), // always cloned, as requested
    }
  }
  /// Copy the structure and clone the original values.
  /// This is always a deep copy.
  pub fn to_owned(&self) -> Type<'static> {
    Type {
      cow: Cow::Owned(str::to_owned(self.cow.borrow())),
      owned: self.owned.clone(), // always cloned, as requested
    }
  }
  /// Copy the structure and reference the original values.
  /// This is always a deep copy of the structure.
  pub fn to_borrowed(&self) -> Type {
    Type {
      cow: Cow::Borrowed(self.cow.borrow()),
      owned: self.owned.clone(), // always cloned, as requested
    }
  }
}

但实际上每个函数只调用派生出的特质的函数。

如果派生不起作用,可以手动实现并派生到使用它的类型。

泛型

派生宏支持所有类型的泛型:生命周期、类型、常量。前两种带有界限,次数不限。

引用

默认情况下不支持引用,因为它们不能转换为拥有类型。

但可以指定哪些生命周期仅用于引用,然后这些引用将被始终复制(引用),因此生命周期不会改变。

请注意,不仅包含引用的类型需要标记,还包含该类型的类型也需要标记。

示例

#[derive(IntoOwned, ToBorrowed, ToOwned)]
#[ownable(reference = "'b")]
pub struct Inner<'a, 'b> {
  cow: Cow<'a, str>,
  referenced: &'b str,
}

// Also types, containing types with references, must be marked.
#[derive(IntoOwned, ToBorrowed, ToOwned)]
#[ownable(reference = "'b")]
pub struct Outer<'a, 'b> {
  inner: Inner<'a, 'b>,
}

将派生具有这些签名的函数

impl<'b> Inner<'_, 'b> {
    pub fn into_owned(self) -> Inner<'static, 'b> {
        // Call the trait, which is also derived
    }
    pub fn to_owned(&self) -> Inner<'static, 'b> {
        // Call the trait, which is also derived
    }
    pub fn to_borrowed(&self) -> Inner<'_, 'b> {
        // Call the trait, which is also derived
    }
}

// The `Outer` will look similar.

可能的错误

如果发生以下错误,则某个字段缺少特质。

error[E0277]: the trait bound `String: IntoOwned` is not satisfied

有时可以通过将 #[ownable)] 作为示例中的示例添加到字段中来修复,否则 AsCopy/AsClone 有助于解决这个问题。

作为最后的手段,可以手动编写周围结构的 impl。

属性

clone

使用 #[ownable(clone)]#[ownable(clone = false|true)],可以表示这个枚举|结构体/变体/字段应该始终被克隆。它可以被覆盖(即在上层设置为 true,然后在不需要克隆的字段设置为 false)。

例如,请参见上方的示例。

函数

在顶层(枚举/结构体)使用 #[ownable(function = false)] 时,上述函数未实现,只有特型。

参考

使用 #[ownable(reference = "..")] 可以提供一个或多个逗号分隔的生命周期,用于引用,请参见上方的引用

AsCopy/AsClone

如果复制类型的实现不足,或者 #[ownable(clone)] 在那个位置不起作用,那么可以使用 AsCopyAsClone 来包装一个值,这样它在这个环境中就能按预期工作。两者都是透明的,并且只使用与原始类型完全相同的空间,所有的实现(Eq、Display、Hash、...)都只将调用传递给内部类型。

示例

更复杂类型的示例

#[derive(IntoOwned, ToBorrowed, ToOwned)]
pub struct Type<'a> {
  cow: Cow<'a, str>,
  nested: Option<Box<Type<'a>>>,
  map: HashMap<AsClone<String>, Cow<'a, str>>,
  #[ownable(clone)] owned: String, // always clone this field
  number: usize, // many copy types have a trait impl, and thus can be used without the `#[ownable(clone)]`
}

特性

  • std - 对于不在核心或 alloc(目前为 HashMapHashSet)中的类型,也实现了特型。

std 默认启用。

用法

使用默认设置(包括 std

[dependencies]
ownable = "0.5"

使用 no_std(但仍需要 alloc)

[dependencies]
ownable = { version = "0.5", default-features = false }

许可

此项目可根据您的选择使用以下任一许可

贡献

除非您明确说明,否则您提交给作品以供包含的任何贡献,根据 Apache-2.0 许可证定义,将根据上述内容双许可,不附加任何额外条款或条件。

依赖项

~270–710KB
~16K SLoC