# borrowme [github](https://github.com/udoprog/borrowme) [crates.io](https://crates.io/crates/borrowme) [docs.rs](https://docs.rs/borrowme) [build status](https://github.com/udoprog/borrowme/actions?query=branch%3Amain) The missing compound borrowing for Rust. Rust comes with two sibling traits which that can convert from owned to borrowed: [`ToOwned`][std-to-owned], [`Borrow`][std-borrow] and [`BorrowMut`][std-borrow-mut]. These can convert most simple types such as `&str` to and from `String`. But lets think of this in a broader perspective. How to we convert a type that *has lifetimes*, to one which *does not*? This crate defines its own [`ToOwned`], [`Borrow`] and [`BorrowMut`] traits which serve a similar purpose to the ones in `std` but are implemented so that they can do this not only for simple references but also for *compound types* which receives lifetimes. To help us implement these traits the [`#[borrowme]`][borrowme] attribute macro is provided ([see this section][borrowme-derive] for why it's not a derive). ```rust #[borrowme] #[derive(Clone)] #[borrowed_attr(derive(Copy))] struct Word<'a> { text: &'a str, } ``` From this we get the following types and implementations: ```rust #[derive(Clone, Copy)] struct Word<'a> { text: &'a str, } #[derive(Clone)] struct OwnedWord { text: String, } impl borrowme::ToOwned for Word<'_> { type Owned = OwnedWord; fn to_owned(&self) -> OwnedWord { /* .. */ } } impl borrowme::Borrow for OwnedWord { type Target<'a> = Word<'a>; fn borrow(&self) -> Word<'_> { /* .. */ } } ``` By itself this isn't much, but here's the big trick. Types using this crate can be composed and converted into their borrowed or owned counterparts as needed: ```rust use std::collections::HashMap; #[borrowme] struct Word<'a> { text: &'a str, } #[borrowme] struct Dictionary<'a> { words: HashMap<&'a str, Word<'a>>, } let dictionary = Dictionary { /* .. */ }; let owned_dictionary: OwnedDictionary = borrowme::to_owned(&dictionary); let dictionary2: Dictionary<'_> = borrowme::borrow(&owned_dictionary); ```
[`Borrow`]: https://docs.rs/borrowme/latest/borrowme/trait.Borrow.html [`BorrowMut`]: https://docs.rs/borrowme/latest/borrowme/trait.BorrowMut.html [`ToOwned`]: https://docs.rs/borrowme/latest/borrowme/trait.ToOwned.html [borrowme-derive]: https://docs.rs/borrowme/latest/borrowme/attr.borrowme.html#why-isnt-this-a-derive [borrowme]: https://docs.rs/borrowme/latest/borrowme/attr.borrowme.html [generic associated types]: https://blog.rust-lang.org/2022/10/28/gats-stabilization.html [std-borrow-mut]: https://doc.rust-lang.org/std/borrow/trait.BorrowMut.html [std-borrow]: https://doc.rust-lang.org/std/borrow/trait.Borrow.html [std-to-owned]: https://doc.rust-lang.org/std/borrow/trait.ToOwned.html