1 unstable release
new 0.1.0 | Dec 16, 2024 |
---|
#1858 in Rust patterns
117 downloads per month
17KB
294 lines
A no_std
set of utilities for more flexible borrowing than the ones
provided by the standard library.
Due to Rust's lack of complete support for Higher Kinded Types (HKTs), borrowing is not as powerful as it could be. Even with the introduction of limited Generic Associated Types (GATs) in Rust 1.65, the standard library has not gained useful APIs that take advantage of this functionality for better borrowing.
This crate introduces more flexible traits for working with borrowed data, especially with types containing internal borrows, by relying on the HKT framework introduced by generic-std. Compiler support for GATs is not required.
Features
This crate replaces std::borrow with more flexible types and traits.
More Flexible Borrowing
[Borrow] and [BorrowMut] are similar to the ones provided by the standard library, but the borrowed type may be an arbitrary type. For example, Borrow::borrow might directly return an std::borrow::Cow.
Saner ToOwned
[ToOwned] is not tied to the borrow trait anymore and provides a
ToOwned::into_owned method. Also, no blanket implementation for Clone
types so something like Cow::<'a, T>::to_owned
is finally able to return
the much saner Cow<'static, T>
.
Clone-On-Write For Types With Internal References
std::borrow::Cow stores either the owned or the borrowed version of another type, but the borrowed variant is required to be a reference. The [Cow] type provided by this crate integrates with [Borrow] and [ToOwned], allowing the borrowed variant to contain a non-reference type with internal references.
Example
Suppose you have a Identifier<'a>
type that internally contains either a
borrowed or an owned string and you would like to create an
Identifier<'static>
to store somewhere. This is not possible with
std::borrow::ToOwned because std::borrow::ToOwned::Owned must implement
std::borrow::Borrow, and std::borrow::Borrow::borrow must return a
reference, not Identifier<'a>
. But doing this is trivial with this crate's
[ToOwned]:
impl<'a> ToOwned for Identifier<'a> {
type Owned = Identifier<'static>;
fn to_owned(&self) -> Self::Owned {
// Returns an `Identifier<'static>`
# unimplemented!()
}
}
Similarly, this crate's [Borrow] can return Identifier<'a>
directly in
addition to normal references:
struct BorrowIdentifier;
impl<'a> BorrowHkt<'a> for BorrowIdentifier {
type T = Identifier<'a>;
}
impl<'a> Borrow<'a, BorrowIdentifier> for Identifier<'a> {
fn borrow<'b>(&'a self) -> Borrowed<'b, BorrowIdentifier>
where
'a: 'b
{
// Returns an `Identifier<'b>`
# unimplemented!()
}
}
struct BorrowIdentifierStr;
impl<'a> BorrowHkt<'a> for BorrowIdentifierStr {
type T = &'a str;
}
impl<'a> Borrow<'a, BorrowIdentifierStr> for Identifier<'a> {
fn borrow<'b>(&'a self) -> Borrowed<'b, BorrowIdentifierStr>
where
'a: 'b
{
// Returns a `&'b str`
# unimplemented!()
}
}