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
每月下载量 637
在 6 个 crate 中使用(通过 rc-zip)
37KB
656 行(不含注释)
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)]
在那个位置不起作用,那么可以使用 AsCopy
和 AsClone
来包装一个值,这样它在这个环境中就能按预期工作。两者都是透明的,并且只使用与原始类型完全相同的空间,所有的实现(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(目前为HashMap
和HashSet
)中的类型,也实现了特型。
std
默认启用。
用法
使用默认设置(包括 std
)
[dependencies]
ownable = "0.5"
使用 no_std
(但仍需要 alloc)
[dependencies]
ownable = { version = "0.5", default-features = false }
许可
此项目可根据您的选择使用以下任一许可
。
贡献
除非您明确说明,否则您提交给作品以供包含的任何贡献,根据 Apache-2.0 许可证定义,将根据上述内容双许可,不附加任何额外条款或条件。
依赖项
~270–710KB
~16K SLoC