├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - nightly 4 | - beta 5 | - stable 6 | before_script: 7 | - | 8 | pip install 'travis-cargo<0.2' --user && 9 | export PATH=$HOME/.local/bin:$PATH 10 | script: 11 | - | 12 | travis-cargo build && 13 | travis-cargo test && 14 | travis-cargo bench && 15 | travis-cargo --only stable doc 16 | after_success: 17 | - travis-cargo --only stable doc-upload 18 | env: 19 | global: 20 | - TRAVIS_CARGO_NIGHTLY_FEATURE="" 21 | - secure: bHizPyUOOWEDjecxCSPyZeOrnNTpLbsFRVO25fW2M5B6FOxsbJwf+ZUXI1VqoAtKBAR0JbY+xpNPTW55ANa/Xyd3/daKFxah/jriiJ+RzRf5/iCyx2ik6tp2Z4LmRZQ/XjyPsQZcPHW9vVxGxW2o8JE78VTmcZwPElLRQoCLlPddDxCmbUpiw0FywkbqFRmG+0M96ymjvl58wvPYRlA76Jd+KoTlehPd+oAmoVRlvYgUZUYUphfDlYN04wXBnSkMqZdiAolkIMAFQ3o9A/W95RUIKiARQe2L9j33/joCMZBme0tq8l6GpmaLpmiXGqKdUlHOJF3cqAPQO1Kve0whNBs4/QlH0xgav6rQcLdCLilPkTj/vFXjo9EiZrOsYFXMQ+dAejqg/+JI1LBJqEwMJZKNe6T2vlJfbCyONEHdPtkhdhT26TjO1JCTeLIFa42ejRgA21PZFFsBos7ZdZO75QW5Wrqw2BLVfZVY3kl+rAWwacj3rLnfs32Vy5KmFjG5zTBlu3HQ/LX1J9E7jwBRKTWglnAyfb8E/NXHutX0wdVrdufwGD7bufjL3uHc3fs1wYSb+wBk1HtVMe/1JWgYpiRCPk4Z+NslCgFm1h7HX2QKikHaCzz7F8TJFEzDN9Lv9JVW2RmpEQBM/lKmNMVLrLt8gAaRQbjQFA4tck9rv9g= 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [0.4.1] - 2020-02-27 4 | ### Added 5 | - `map_with_owner` (#51) 6 | 7 | ### Changed 8 | - Use dyn for trait objects (#53) 9 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "owning_ref" 3 | version = "0.4.1" 4 | authors = ["Marvin Löbel "] 5 | license = "MIT" 6 | 7 | description = "A library for creating references that carry their owner with them." 8 | readme = "README.md" 9 | documentation = "http://kimundi.github.io/owning-ref-rs/owning_ref/index.html" 10 | 11 | repository = "https://github.com/Kimundi/owning-ref-rs" 12 | keywords = ["reference", "sibling", "field", "owning"] 13 | 14 | [dependencies] 15 | stable_deref_trait = "1.0.0" 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Marvin Löbel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/Kimundi/owning-ref-rs.svg)](https://travis-ci.org/Kimundi/owning-ref-rs) 2 | [![Crate](https://img.shields.io/crates/v/owning_ref.svg)](https://crates.io/crates/owning_ref) 3 | [![Docs](https://docs.rs/owning_ref/badge.svg)](https://docs.rs/owning_ref) 4 | 5 | owning-ref-rs 6 | ============== 7 | 8 | A library for creating references that carry their owner with them. 9 | 10 | This can sometimes be useful because Rust borrowing rules normally prevent 11 | moving a type that has been borrowed from. For example, this kind of code gets rejected: 12 | 13 | ```rust 14 | fn return_owned_and_referenced<'a>() -> (Vec, &'a [u8]) { 15 | let v = vec![1, 2, 3, 4]; 16 | let s = &v[1..3]; 17 | (v, s) 18 | } 19 | ``` 20 | 21 | This library enables this safe usage by keeping the owner and the reference 22 | bundled together in a wrapper type that ensure that lifetime constraint: 23 | 24 | ```rust 25 | fn return_owned_and_referenced() -> OwningRef, [u8]> { 26 | let v = vec![1, 2, 3, 4]; 27 | let or = OwningRef::new(v); 28 | let or = or.map(|v| &v[1..3]); 29 | or 30 | } 31 | ``` 32 | 33 | ## Getting Started 34 | 35 | To get started, add the following to `Cargo.toml`. 36 | 37 | ```toml 38 | owning_ref = "0.4.1" 39 | ``` 40 | 41 | ...and see the [docs](http://kimundi.github.io/owning-ref-rs/owning_ref/index.html) for how to use it. 42 | 43 | 44 | ## Example 45 | 46 | ```rust 47 | extern crate owning_ref; 48 | use owning_ref::BoxRef; 49 | 50 | fn main() { 51 | // Create an array owned by a Box. 52 | let arr = Box::new([1, 2, 3, 4]) as Box<[i32]>; 53 | 54 | // Transfer into a BoxRef. 55 | let arr: BoxRef<[i32]> = BoxRef::new(arr); 56 | assert_eq!(&*arr, &[1, 2, 3, 4]); 57 | 58 | // We can slice the array without losing ownership or changing type. 59 | let arr: BoxRef<[i32]> = arr.map(|arr| &arr[1..3]); 60 | assert_eq!(&*arr, &[2, 3]); 61 | 62 | // Also works for Arc, Rc, String and Vec! 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![warn(missing_docs)] 2 | 3 | /*! 4 | # An owning reference. 5 | 6 | This crate provides the _owning reference_ types `OwningRef` and `OwningRefMut` 7 | that enables it to bundle a reference together with the owner of the data it points to. 8 | This allows moving and dropping of a `OwningRef` without needing to recreate the reference. 9 | 10 | This can sometimes be useful because Rust borrowing rules normally prevent 11 | moving a type that has been moved from. For example, this kind of code gets rejected: 12 | 13 | ```rust,ignore 14 | fn return_owned_and_referenced<'a>() -> (Vec, &'a [u8]) { 15 | let v = vec![1, 2, 3, 4]; 16 | let s = &v[1..3]; 17 | (v, s) 18 | } 19 | ``` 20 | 21 | Even though, from a memory-layout point of view, this can be entirely safe 22 | if the new location of the vector still lives longer than the lifetime `'a` 23 | of the reference because the backing allocation of the vector does not change. 24 | 25 | This library enables this safe usage by keeping the owner and the reference 26 | bundled together in a wrapper type that ensure that lifetime constraint: 27 | 28 | ```rust 29 | # extern crate owning_ref; 30 | # use owning_ref::OwningRef; 31 | # fn main() { 32 | fn return_owned_and_referenced() -> OwningRef, [u8]> { 33 | let v = vec![1, 2, 3, 4]; 34 | let or = OwningRef::new(v); 35 | let or = or.map(|v| &v[1..3]); 36 | or 37 | } 38 | # } 39 | ``` 40 | 41 | It works by requiring owner types to dereference to stable memory locations 42 | and preventing mutable access to root containers, which in practice requires heap allocation 43 | as provided by `Box`, `Rc`, etc. 44 | 45 | Also provided are typedefs for common owner type combinations, 46 | which allow for less verbose type signatures. For example, `BoxRef` instead of `OwningRef, T>`. 47 | 48 | The crate also provides the more advanced `OwningHandle` type, 49 | which allows more freedom in bundling a dependent handle object 50 | along with the data it depends on, at the cost of some unsafe needed in the API. 51 | See the documentation around `OwningHandle` for more details. 52 | 53 | # Examples 54 | 55 | ## Basics 56 | 57 | ``` 58 | extern crate owning_ref; 59 | use owning_ref::BoxRef; 60 | 61 | fn main() { 62 | // Create an array owned by a Box. 63 | let arr = Box::new([1, 2, 3, 4]) as Box<[i32]>; 64 | 65 | // Transfer into a BoxRef. 66 | let arr: BoxRef<[i32]> = BoxRef::new(arr); 67 | assert_eq!(&*arr, &[1, 2, 3, 4]); 68 | 69 | // We can slice the array without losing ownership or changing type. 70 | let arr: BoxRef<[i32]> = arr.map(|arr| &arr[1..3]); 71 | assert_eq!(&*arr, &[2, 3]); 72 | 73 | // Also works for Arc, Rc, String and Vec! 74 | } 75 | ``` 76 | 77 | ## Caching a reference to a struct field 78 | 79 | ``` 80 | extern crate owning_ref; 81 | use owning_ref::BoxRef; 82 | 83 | fn main() { 84 | struct Foo { 85 | tag: u32, 86 | x: u16, 87 | y: u16, 88 | z: u16, 89 | } 90 | let foo = Foo { tag: 1, x: 100, y: 200, z: 300 }; 91 | 92 | let or = BoxRef::new(Box::new(foo)).map(|foo| { 93 | match foo.tag { 94 | 0 => &foo.x, 95 | 1 => &foo.y, 96 | 2 => &foo.z, 97 | _ => panic!(), 98 | } 99 | }); 100 | 101 | assert_eq!(*or, 200); 102 | } 103 | ``` 104 | 105 | ## Caching a reference to an entry in a vector 106 | 107 | ``` 108 | extern crate owning_ref; 109 | use owning_ref::VecRef; 110 | 111 | fn main() { 112 | let v = VecRef::new(vec![1, 2, 3, 4, 5]).map(|v| &v[3]); 113 | assert_eq!(*v, 4); 114 | } 115 | ``` 116 | 117 | ## Caching a subslice of a String 118 | 119 | ``` 120 | extern crate owning_ref; 121 | use owning_ref::StringRef; 122 | 123 | fn main() { 124 | let s = StringRef::new("hello world".to_owned()) 125 | .map(|s| s.split(' ').nth(1).unwrap()); 126 | 127 | assert_eq!(&*s, "world"); 128 | } 129 | ``` 130 | 131 | ## Reference counted slices that share ownership of the backing storage 132 | 133 | ``` 134 | extern crate owning_ref; 135 | use owning_ref::RcRef; 136 | use std::rc::Rc; 137 | 138 | fn main() { 139 | let rc: RcRef<[i32]> = RcRef::new(Rc::new([1, 2, 3, 4]) as Rc<[i32]>); 140 | assert_eq!(&*rc, &[1, 2, 3, 4]); 141 | 142 | let rc_a: RcRef<[i32]> = rc.clone().map(|s| &s[0..2]); 143 | let rc_b = rc.clone().map(|s| &s[1..3]); 144 | let rc_c = rc.clone().map(|s| &s[2..4]); 145 | assert_eq!(&*rc_a, &[1, 2]); 146 | assert_eq!(&*rc_b, &[2, 3]); 147 | assert_eq!(&*rc_c, &[3, 4]); 148 | 149 | let rc_c_a = rc_c.clone().map(|s| &s[1]); 150 | assert_eq!(&*rc_c_a, &4); 151 | } 152 | ``` 153 | 154 | ## Atomic reference counted slices that share ownership of the backing storage 155 | 156 | ``` 157 | extern crate owning_ref; 158 | use owning_ref::ArcRef; 159 | use std::sync::Arc; 160 | 161 | fn main() { 162 | use std::thread; 163 | 164 | fn par_sum(rc: ArcRef<[i32]>) -> i32 { 165 | if rc.len() == 0 { 166 | return 0; 167 | } else if rc.len() == 1 { 168 | return rc[0]; 169 | } 170 | let mid = rc.len() / 2; 171 | let left = rc.clone().map(|s| &s[..mid]); 172 | let right = rc.map(|s| &s[mid..]); 173 | 174 | let left = thread::spawn(move || par_sum(left)); 175 | let right = thread::spawn(move || par_sum(right)); 176 | 177 | left.join().unwrap() + right.join().unwrap() 178 | } 179 | 180 | let rc: Arc<[i32]> = Arc::new([1, 2, 3, 4]); 181 | let rc: ArcRef<[i32]> = rc.into(); 182 | 183 | assert_eq!(par_sum(rc), 10); 184 | } 185 | ``` 186 | 187 | ## References into RAII locks 188 | 189 | ``` 190 | extern crate owning_ref; 191 | use owning_ref::RefRef; 192 | use std::cell::{RefCell, Ref}; 193 | 194 | fn main() { 195 | let refcell = RefCell::new((1, 2, 3, 4)); 196 | // Also works with Mutex and RwLock 197 | 198 | let refref = { 199 | let refref = RefRef::new(refcell.borrow()).map(|x| &x.3); 200 | assert_eq!(*refref, 4); 201 | 202 | // We move the RAII lock and the reference to one of 203 | // the subfields in the data it guards here: 204 | refref 205 | }; 206 | 207 | assert_eq!(*refref, 4); 208 | 209 | drop(refref); 210 | 211 | assert_eq!(*refcell.borrow(), (1, 2, 3, 4)); 212 | } 213 | ``` 214 | 215 | ## Mutable reference 216 | 217 | When the owned container implements `DerefMut`, it is also possible to make 218 | a _mutable owning reference_. (E.g. with `Box`, `RefMut`, `MutexGuard`) 219 | 220 | ``` 221 | extern crate owning_ref; 222 | use owning_ref::RefMutRefMut; 223 | use std::cell::{RefCell, RefMut}; 224 | 225 | fn main() { 226 | let refcell = RefCell::new((1, 2, 3, 4)); 227 | 228 | let mut refmut_refmut = { 229 | let mut refmut_refmut = RefMutRefMut::new(refcell.borrow_mut()).map_mut(|x| &mut x.3); 230 | assert_eq!(*refmut_refmut, 4); 231 | *refmut_refmut *= 2; 232 | 233 | refmut_refmut 234 | }; 235 | 236 | assert_eq!(*refmut_refmut, 8); 237 | *refmut_refmut *= 2; 238 | 239 | drop(refmut_refmut); 240 | 241 | assert_eq!(*refcell.borrow(), (1, 2, 3, 16)); 242 | } 243 | ``` 244 | */ 245 | 246 | extern crate stable_deref_trait; 247 | pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as CloneStableAddress}; 248 | 249 | /// An owning reference. 250 | /// 251 | /// This wraps an owner `O` and a reference `&T` pointing 252 | /// at something reachable from `O::Target` while keeping 253 | /// the ability to move `self` around. 254 | /// 255 | /// The owner is usually a pointer that points at some base type. 256 | /// 257 | /// For more details and examples, see the module and method docs. 258 | pub struct OwningRef { 259 | owner: O, 260 | reference: *const T, 261 | } 262 | 263 | /// An mutable owning reference. 264 | /// 265 | /// This wraps an owner `O` and a reference `&mut T` pointing 266 | /// at something reachable from `O::Target` while keeping 267 | /// the ability to move `self` around. 268 | /// 269 | /// The owner is usually a pointer that points at some base type. 270 | /// 271 | /// For more details and examples, see the module and method docs. 272 | pub struct OwningRefMut { 273 | owner: O, 274 | reference: *mut T, 275 | } 276 | 277 | /// Helper trait for an erased concrete type an owner dereferences to. 278 | /// This is used in form of a trait object for keeping 279 | /// something around to (virtually) call the destructor. 280 | pub trait Erased {} 281 | impl Erased for T {} 282 | 283 | /// Helper trait for erasing the concrete type of what an owner derferences to, 284 | /// for example `Box -> Box`. This would be unneeded with 285 | /// higher kinded types support in the language. 286 | pub unsafe trait IntoErased<'a> { 287 | /// Owner with the dereference type substituted to `Erased`. 288 | type Erased; 289 | /// Perform the type erasure. 290 | fn into_erased(self) -> Self::Erased; 291 | } 292 | 293 | ///////////////////////////////////////////////////////////////////////////// 294 | // OwningRef 295 | ///////////////////////////////////////////////////////////////////////////// 296 | 297 | impl OwningRef { 298 | /// Creates a new owning reference from a owner 299 | /// initialized to the direct dereference of it. 300 | /// 301 | /// # Example 302 | /// ``` 303 | /// extern crate owning_ref; 304 | /// use owning_ref::OwningRef; 305 | /// 306 | /// fn main() { 307 | /// let owning_ref = OwningRef::new(Box::new(42)); 308 | /// assert_eq!(*owning_ref, 42); 309 | /// } 310 | /// ``` 311 | pub fn new(o: O) -> Self 312 | where O: StableAddress, 313 | O: Deref, 314 | { 315 | OwningRef { 316 | reference: &*o, 317 | owner: o, 318 | } 319 | } 320 | 321 | /// Like `new`, but doesn’t require `O` to implement the `StableAddress` trait. 322 | /// Instead, the caller is responsible to make the same promises as implementing the trait. 323 | /// 324 | /// This is useful for cases where coherence rules prevents implementing the trait 325 | /// without adding a dependency to this crate in a third-party library. 326 | pub unsafe fn new_assert_stable_address(o: O) -> Self 327 | where O: Deref, 328 | { 329 | OwningRef { 330 | reference: &*o, 331 | owner: o, 332 | } 333 | } 334 | 335 | /// Converts `self` into a new owning reference that points at something reachable 336 | /// from the previous one. 337 | /// 338 | /// This can be a reference to a field of `U`, something reachable from a field of 339 | /// `U`, or even something unrelated with a `'static` lifetime. 340 | /// 341 | /// # Example 342 | /// ``` 343 | /// extern crate owning_ref; 344 | /// use owning_ref::OwningRef; 345 | /// 346 | /// fn main() { 347 | /// let owning_ref = OwningRef::new(Box::new([1, 2, 3, 4])); 348 | /// 349 | /// // create a owning reference that points at the 350 | /// // third element of the array. 351 | /// let owning_ref = owning_ref.map(|array| &array[2]); 352 | /// assert_eq!(*owning_ref, 3); 353 | /// } 354 | /// ``` 355 | pub fn map(self, f: F) -> OwningRef 356 | where O: StableAddress, 357 | F: FnOnce(&T) -> &U 358 | { 359 | OwningRef { 360 | reference: f(&self), 361 | owner: self.owner, 362 | } 363 | } 364 | 365 | /// Converts `self` into a new owning reference that points at something reachable 366 | /// from the previous one or from the owner itself. 367 | /// 368 | /// This can be a reference to a field of `U`, something reachable from a field of 369 | /// `U` or from the owner `O`, or even something unrelated with a `'static` lifetime. 370 | /// 371 | /// # Example 372 | /// ``` 373 | /// extern crate owning_ref; 374 | /// use owning_ref::OwningRef; 375 | /// 376 | /// fn main() { 377 | /// let owning_ref = OwningRef::new(Box::new([1, 2, 3, 4])); 378 | /// let owning_ref = owning_ref.map(|array| &array[2]); 379 | /// assert_eq!(*owning_ref, 3); 380 | /// 381 | /// // create a owning reference that points at the 382 | /// // second element of the array from the owning ref that was pointing to the third 383 | /// let owning_ref = owning_ref.map_with_owner(|array, _prev| &array[1]); 384 | /// assert_eq!(*owning_ref, 2); 385 | /// } 386 | /// ``` 387 | pub fn map_with_owner(self, f: F) -> OwningRef 388 | where O: StableAddress, 389 | F: for<'a> FnOnce(&'a O, &'a T) -> &'a U 390 | { 391 | OwningRef { 392 | reference: f(&self.owner, &self), 393 | owner: self.owner, 394 | } 395 | } 396 | 397 | /// Tries to convert `self` into a new owning reference that points 398 | /// at something reachable from the previous one. 399 | /// 400 | /// This can be a reference to a field of `U`, something reachable from a field of 401 | /// `U`, or even something unrelated with a `'static` lifetime. 402 | /// 403 | /// # Example 404 | /// ``` 405 | /// extern crate owning_ref; 406 | /// use owning_ref::OwningRef; 407 | /// 408 | /// fn main() { 409 | /// let owning_ref = OwningRef::new(Box::new([1, 2, 3, 4])); 410 | /// 411 | /// // create a owning reference that points at the 412 | /// // third element of the array. 413 | /// let owning_ref = owning_ref.try_map(|array| { 414 | /// if array[2] == 3 { Ok(&array[2]) } else { Err(()) } 415 | /// }); 416 | /// assert_eq!(*owning_ref.unwrap(), 3); 417 | /// } 418 | /// ``` 419 | pub fn try_map(self, f: F) -> Result, E> 420 | where O: StableAddress, 421 | F: FnOnce(&T) -> Result<&U, E> 422 | { 423 | Ok(OwningRef { 424 | reference: f(&self)?, 425 | owner: self.owner, 426 | }) 427 | } 428 | 429 | /// Tries to convert `self` into a new owning reference that points 430 | /// at something reachable from the previous one. 431 | /// 432 | /// This can be a reference to a field of `U`, something reachable from a field of 433 | /// `U`, or even something unrelated with a `'static` lifetime. 434 | /// 435 | /// # Example 436 | /// ``` 437 | /// extern crate owning_ref; 438 | /// use owning_ref::OwningRef; 439 | /// 440 | /// fn main() { 441 | /// let owning_ref = OwningRef::new(Box::new([1, 2, 3, 4])); 442 | /// let owning_ref = owning_ref.map(|array| &array[2]); 443 | /// 444 | /// // create a owning reference that points at the 445 | /// // second element of the array from the owning ref that was pointing to the third 446 | /// let owning_ref = owning_ref.try_map_with_owner(|array, _prev| { 447 | /// if array[1] == 2 { Ok(&array[1]) } else { Err(()) } 448 | /// }); 449 | /// assert_eq!(*owning_ref.unwrap(), 2); 450 | /// } 451 | /// ``` 452 | pub fn try_map_with_owner(self, f: F) -> Result, E> 453 | where O: StableAddress, 454 | F: for<'a> FnOnce(&'a O, &'a T) -> Result<&'a U, E> 455 | { 456 | Ok(OwningRef { 457 | reference: f(&self.owner, &self)?, 458 | owner: self.owner, 459 | }) 460 | } 461 | 462 | /// Converts `self` into a new owning reference with a different owner type. 463 | /// 464 | /// The new owner type needs to still contain the original owner in some way 465 | /// so that the reference into it remains valid. This function is marked unsafe 466 | /// because the user needs to manually uphold this guarantee. 467 | pub unsafe fn map_owner(self, f: F) -> OwningRef 468 | where O: StableAddress, 469 | P: StableAddress, 470 | F: FnOnce(O) -> P 471 | { 472 | OwningRef { 473 | reference: self.reference, 474 | owner: f(self.owner), 475 | } 476 | } 477 | 478 | /// Converts `self` into a new owning reference where the owner is wrapped 479 | /// in an additional `Box`. 480 | /// 481 | /// This can be used to safely erase the owner of any `OwningRef` 482 | /// to a `OwningRef, T>`. 483 | pub fn map_owner_box(self) -> OwningRef, T> { 484 | OwningRef { 485 | reference: self.reference, 486 | owner: Box::new(self.owner), 487 | } 488 | } 489 | 490 | /// Erases the concrete base type of the owner with a trait object. 491 | /// 492 | /// This allows mixing of owned references with different owner base types. 493 | /// 494 | /// # Example 495 | /// ``` 496 | /// extern crate owning_ref; 497 | /// use owning_ref::{OwningRef, Erased}; 498 | /// 499 | /// fn main() { 500 | /// // NB: Using the concrete types here for explicitnes. 501 | /// // For less verbose code type aliases like `BoxRef` are provided. 502 | /// 503 | /// let owning_ref_a: OwningRef, [i32; 4]> 504 | /// = OwningRef::new(Box::new([1, 2, 3, 4])); 505 | /// 506 | /// let owning_ref_b: OwningRef>, Vec<(i32, bool)>> 507 | /// = OwningRef::new(Box::new(vec![(0, false), (1, true)])); 508 | /// 509 | /// let owning_ref_a: OwningRef, i32> 510 | /// = owning_ref_a.map(|a| &a[0]); 511 | /// 512 | /// let owning_ref_b: OwningRef>, i32> 513 | /// = owning_ref_b.map(|a| &a[1].0); 514 | /// 515 | /// let owning_refs: [OwningRef, i32>; 2] 516 | /// = [owning_ref_a.erase_owner(), owning_ref_b.erase_owner()]; 517 | /// 518 | /// assert_eq!(*owning_refs[0], 1); 519 | /// assert_eq!(*owning_refs[1], 1); 520 | /// } 521 | /// ``` 522 | pub fn erase_owner<'a>(self) -> OwningRef 523 | where O: IntoErased<'a>, 524 | { 525 | OwningRef { 526 | reference: self.reference, 527 | owner: self.owner.into_erased(), 528 | } 529 | } 530 | 531 | // TODO: wrap_owner 532 | 533 | /// A reference to the underlying owner. 534 | pub fn as_owner(&self) -> &O { 535 | &self.owner 536 | } 537 | 538 | /// Discards the reference and retrieves the owner. 539 | pub fn into_owner(self) -> O { 540 | self.owner 541 | } 542 | } 543 | 544 | impl OwningRefMut { 545 | /// Creates a new owning reference from a owner 546 | /// initialized to the direct dereference of it. 547 | /// 548 | /// # Example 549 | /// ``` 550 | /// extern crate owning_ref; 551 | /// use owning_ref::OwningRefMut; 552 | /// 553 | /// fn main() { 554 | /// let owning_ref_mut = OwningRefMut::new(Box::new(42)); 555 | /// assert_eq!(*owning_ref_mut, 42); 556 | /// } 557 | /// ``` 558 | pub fn new(mut o: O) -> Self 559 | where O: StableAddress, 560 | O: DerefMut, 561 | { 562 | OwningRefMut { 563 | reference: &mut *o, 564 | owner: o, 565 | } 566 | } 567 | 568 | /// Like `new`, but doesn’t require `O` to implement the `StableAddress` trait. 569 | /// Instead, the caller is responsible to make the same promises as implementing the trait. 570 | /// 571 | /// This is useful for cases where coherence rules prevents implementing the trait 572 | /// without adding a dependency to this crate in a third-party library. 573 | pub unsafe fn new_assert_stable_address(mut o: O) -> Self 574 | where O: DerefMut, 575 | { 576 | OwningRefMut { 577 | reference: &mut *o, 578 | owner: o, 579 | } 580 | } 581 | 582 | /// Converts `self` into a new _shared_ owning reference that points at 583 | /// something reachable from the previous one. 584 | /// 585 | /// This can be a reference to a field of `U`, something reachable from a field of 586 | /// `U`, or even something unrelated with a `'static` lifetime. 587 | /// 588 | /// # Example 589 | /// ``` 590 | /// extern crate owning_ref; 591 | /// use owning_ref::OwningRefMut; 592 | /// 593 | /// fn main() { 594 | /// let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4])); 595 | /// 596 | /// // create a owning reference that points at the 597 | /// // third element of the array. 598 | /// let owning_ref = owning_ref_mut.map(|array| &array[2]); 599 | /// assert_eq!(*owning_ref, 3); 600 | /// } 601 | /// ``` 602 | pub fn map(mut self, f: F) -> OwningRef 603 | where O: StableAddress, 604 | F: FnOnce(&mut T) -> &U 605 | { 606 | OwningRef { 607 | reference: f(&mut self), 608 | owner: self.owner, 609 | } 610 | } 611 | 612 | /// Converts `self` into a new _mutable_ owning reference that points at 613 | /// something reachable from the previous one. 614 | /// 615 | /// This can be a reference to a field of `U`, something reachable from a field of 616 | /// `U`, or even something unrelated with a `'static` lifetime. 617 | /// 618 | /// # Example 619 | /// ``` 620 | /// extern crate owning_ref; 621 | /// use owning_ref::OwningRefMut; 622 | /// 623 | /// fn main() { 624 | /// let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4])); 625 | /// 626 | /// // create a owning reference that points at the 627 | /// // third element of the array. 628 | /// let owning_ref_mut = owning_ref_mut.map_mut(|array| &mut array[2]); 629 | /// assert_eq!(*owning_ref_mut, 3); 630 | /// } 631 | /// ``` 632 | pub fn map_mut(mut self, f: F) -> OwningRefMut 633 | where O: StableAddress, 634 | F: FnOnce(&mut T) -> &mut U 635 | { 636 | OwningRefMut { 637 | reference: f(&mut self), 638 | owner: self.owner, 639 | } 640 | } 641 | 642 | /// Tries to convert `self` into a new _shared_ owning reference that points 643 | /// at something reachable from the previous one. 644 | /// 645 | /// This can be a reference to a field of `U`, something reachable from a field of 646 | /// `U`, or even something unrelated with a `'static` lifetime. 647 | /// 648 | /// # Example 649 | /// ``` 650 | /// extern crate owning_ref; 651 | /// use owning_ref::OwningRefMut; 652 | /// 653 | /// fn main() { 654 | /// let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4])); 655 | /// 656 | /// // create a owning reference that points at the 657 | /// // third element of the array. 658 | /// let owning_ref = owning_ref_mut.try_map(|array| { 659 | /// if array[2] == 3 { Ok(&array[2]) } else { Err(()) } 660 | /// }); 661 | /// assert_eq!(*owning_ref.unwrap(), 3); 662 | /// } 663 | /// ``` 664 | pub fn try_map(mut self, f: F) -> Result, E> 665 | where O: StableAddress, 666 | F: FnOnce(&mut T) -> Result<&U, E> 667 | { 668 | Ok(OwningRef { 669 | reference: f(&mut self)?, 670 | owner: self.owner, 671 | }) 672 | } 673 | 674 | /// Tries to convert `self` into a new _mutable_ owning reference that points 675 | /// at something reachable from the previous one. 676 | /// 677 | /// This can be a reference to a field of `U`, something reachable from a field of 678 | /// `U`, or even something unrelated with a `'static` lifetime. 679 | /// 680 | /// # Example 681 | /// ``` 682 | /// extern crate owning_ref; 683 | /// use owning_ref::OwningRefMut; 684 | /// 685 | /// fn main() { 686 | /// let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4])); 687 | /// 688 | /// // create a owning reference that points at the 689 | /// // third element of the array. 690 | /// let owning_ref_mut = owning_ref_mut.try_map_mut(|array| { 691 | /// if array[2] == 3 { Ok(&mut array[2]) } else { Err(()) } 692 | /// }); 693 | /// assert_eq!(*owning_ref_mut.unwrap(), 3); 694 | /// } 695 | /// ``` 696 | pub fn try_map_mut(mut self, f: F) -> Result, E> 697 | where O: StableAddress, 698 | F: FnOnce(&mut T) -> Result<&mut U, E> 699 | { 700 | Ok(OwningRefMut { 701 | reference: f(&mut self)?, 702 | owner: self.owner, 703 | }) 704 | } 705 | 706 | /// Converts `self` into a new owning reference with a different owner type. 707 | /// 708 | /// The new owner type needs to still contain the original owner in some way 709 | /// so that the reference into it remains valid. This function is marked unsafe 710 | /// because the user needs to manually uphold this guarantee. 711 | pub unsafe fn map_owner(self, f: F) -> OwningRefMut 712 | where O: StableAddress, 713 | P: StableAddress, 714 | F: FnOnce(O) -> P 715 | { 716 | OwningRefMut { 717 | reference: self.reference, 718 | owner: f(self.owner), 719 | } 720 | } 721 | 722 | /// Converts `self` into a new owning reference where the owner is wrapped 723 | /// in an additional `Box`. 724 | /// 725 | /// This can be used to safely erase the owner of any `OwningRefMut` 726 | /// to a `OwningRefMut, T>`. 727 | pub fn map_owner_box(self) -> OwningRefMut, T> { 728 | OwningRefMut { 729 | reference: self.reference, 730 | owner: Box::new(self.owner), 731 | } 732 | } 733 | 734 | /// Erases the concrete base type of the owner with a trait object. 735 | /// 736 | /// This allows mixing of owned references with different owner base types. 737 | /// 738 | /// # Example 739 | /// ``` 740 | /// extern crate owning_ref; 741 | /// use owning_ref::{OwningRefMut, Erased}; 742 | /// 743 | /// fn main() { 744 | /// // NB: Using the concrete types here for explicitnes. 745 | /// // For less verbose code type aliases like `BoxRef` are provided. 746 | /// 747 | /// let owning_ref_mut_a: OwningRefMut, [i32; 4]> 748 | /// = OwningRefMut::new(Box::new([1, 2, 3, 4])); 749 | /// 750 | /// let owning_ref_mut_b: OwningRefMut>, Vec<(i32, bool)>> 751 | /// = OwningRefMut::new(Box::new(vec![(0, false), (1, true)])); 752 | /// 753 | /// let owning_ref_mut_a: OwningRefMut, i32> 754 | /// = owning_ref_mut_a.map_mut(|a| &mut a[0]); 755 | /// 756 | /// let owning_ref_mut_b: OwningRefMut>, i32> 757 | /// = owning_ref_mut_b.map_mut(|a| &mut a[1].0); 758 | /// 759 | /// let owning_refs_mut: [OwningRefMut, i32>; 2] 760 | /// = [owning_ref_mut_a.erase_owner(), owning_ref_mut_b.erase_owner()]; 761 | /// 762 | /// assert_eq!(*owning_refs_mut[0], 1); 763 | /// assert_eq!(*owning_refs_mut[1], 1); 764 | /// } 765 | /// ``` 766 | pub fn erase_owner<'a>(self) -> OwningRefMut 767 | where O: IntoErased<'a>, 768 | { 769 | OwningRefMut { 770 | reference: self.reference, 771 | owner: self.owner.into_erased(), 772 | } 773 | } 774 | 775 | // TODO: wrap_owner 776 | 777 | /// A reference to the underlying owner. 778 | pub fn as_owner(&self) -> &O { 779 | &self.owner 780 | } 781 | 782 | /// A mutable reference to the underlying owner. 783 | pub fn as_owner_mut(&mut self) -> &mut O { 784 | &mut self.owner 785 | } 786 | 787 | /// Discards the reference and retrieves the owner. 788 | pub fn into_owner(self) -> O { 789 | self.owner 790 | } 791 | } 792 | 793 | ///////////////////////////////////////////////////////////////////////////// 794 | // OwningHandle 795 | ///////////////////////////////////////////////////////////////////////////// 796 | 797 | use std::ops::{Deref, DerefMut}; 798 | 799 | /// `OwningHandle` is a complement to `OwningRef`. Where `OwningRef` allows 800 | /// consumers to pass around an owned object and a dependent reference, 801 | /// `OwningHandle` contains an owned object and a dependent _object_. 802 | /// 803 | /// `OwningHandle` can encapsulate a `RefMut` along with its associated 804 | /// `RefCell`, or an `RwLockReadGuard` along with its associated `RwLock`. 805 | /// However, the API is completely generic and there are no restrictions on 806 | /// what types of owning and dependent objects may be used. 807 | /// 808 | /// `OwningHandle` is created by passing an owner object (which dereferences 809 | /// to a stable address) along with a callback which receives a pointer to 810 | /// that stable location. The callback may then dereference the pointer and 811 | /// mint a dependent object, with the guarantee that the returned object will 812 | /// not outlive the referent of the pointer. 813 | /// 814 | /// Since the callback needs to dereference a raw pointer, it requires `unsafe` 815 | /// code. To avoid forcing this unsafety on most callers, the `ToHandle` trait is 816 | /// implemented for common data structures. Types that implement `ToHandle` can 817 | /// be wrapped into an `OwningHandle` without passing a callback. 818 | pub struct OwningHandle 819 | where O: StableAddress, H: Deref, 820 | { 821 | handle: H, 822 | _owner: O, 823 | } 824 | 825 | impl Deref for OwningHandle 826 | where O: StableAddress, H: Deref, 827 | { 828 | type Target = H::Target; 829 | fn deref(&self) -> &H::Target { 830 | self.handle.deref() 831 | } 832 | } 833 | 834 | unsafe impl StableAddress for OwningHandle 835 | where O: StableAddress, H: StableAddress, 836 | {} 837 | 838 | impl DerefMut for OwningHandle 839 | where O: StableAddress, H: DerefMut, 840 | { 841 | fn deref_mut(&mut self) -> &mut H::Target { 842 | self.handle.deref_mut() 843 | } 844 | } 845 | 846 | /// Trait to implement the conversion of owner to handle for common types. 847 | pub trait ToHandle { 848 | /// The type of handle to be encapsulated by the OwningHandle. 849 | type Handle: Deref; 850 | 851 | /// Given an appropriately-long-lived pointer to ourselves, create a 852 | /// handle to be encapsulated by the `OwningHandle`. 853 | unsafe fn to_handle(x: *const Self) -> Self::Handle; 854 | } 855 | 856 | /// Trait to implement the conversion of owner to mutable handle for common types. 857 | pub trait ToHandleMut { 858 | /// The type of handle to be encapsulated by the OwningHandle. 859 | type HandleMut: DerefMut; 860 | 861 | /// Given an appropriately-long-lived pointer to ourselves, create a 862 | /// mutable handle to be encapsulated by the `OwningHandle`. 863 | unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut; 864 | } 865 | 866 | impl OwningHandle 867 | where O: StableAddress, O::Target: ToHandle, H: Deref, 868 | { 869 | /// Create a new `OwningHandle` for a type that implements `ToHandle`. For types 870 | /// that don't implement `ToHandle`, callers may invoke `new_with_fn`, which accepts 871 | /// a callback to perform the conversion. 872 | pub fn new(o: O) -> Self { 873 | OwningHandle::new_with_fn(o, |x| unsafe { O::Target::to_handle(x) }) 874 | } 875 | } 876 | 877 | impl OwningHandle 878 | where O: StableAddress, O::Target: ToHandleMut, H: DerefMut, 879 | { 880 | /// Create a new mutable `OwningHandle` for a type that implements `ToHandleMut`. 881 | pub fn new_mut(o: O) -> Self { 882 | OwningHandle::new_with_fn(o, |x| unsafe { O::Target::to_handle_mut(x) }) 883 | } 884 | } 885 | 886 | impl OwningHandle 887 | where O: StableAddress, H: Deref, 888 | { 889 | /// Create a new OwningHandle. The provided callback will be invoked with 890 | /// a pointer to the object owned by `o`, and the returned value is stored 891 | /// as the object to which this `OwningHandle` will forward `Deref` and 892 | /// `DerefMut`. 893 | pub fn new_with_fn(o: O, f: F) -> Self 894 | where F: FnOnce(*const O::Target) -> H 895 | { 896 | let h: H; 897 | { 898 | h = f(o.deref() as *const O::Target); 899 | } 900 | 901 | OwningHandle { 902 | handle: h, 903 | _owner: o, 904 | } 905 | } 906 | 907 | /// Create a new OwningHandle. The provided callback will be invoked with 908 | /// a pointer to the object owned by `o`, and the returned value is stored 909 | /// as the object to which this `OwningHandle` will forward `Deref` and 910 | /// `DerefMut`. 911 | pub fn try_new(o: O, f: F) -> Result 912 | where F: FnOnce(*const O::Target) -> Result 913 | { 914 | let h: H; 915 | { 916 | h = f(o.deref() as *const O::Target)?; 917 | } 918 | 919 | Ok(OwningHandle { 920 | handle: h, 921 | _owner: o, 922 | }) 923 | } 924 | 925 | /// A getter for the underlying owner. 926 | pub fn as_owner(&self) -> &O { 927 | &self._owner 928 | } 929 | 930 | /// Discards the dependent object and returns the owner. 931 | pub fn into_owner(self) -> O { 932 | self._owner 933 | } 934 | } 935 | 936 | ///////////////////////////////////////////////////////////////////////////// 937 | // std traits 938 | ///////////////////////////////////////////////////////////////////////////// 939 | 940 | use std::convert::From; 941 | use std::fmt::{self, Debug}; 942 | use std::marker::{Send, Sync}; 943 | use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering}; 944 | use std::hash::{Hash, Hasher}; 945 | use std::borrow::Borrow; 946 | 947 | impl Deref for OwningRef { 948 | type Target = T; 949 | 950 | fn deref(&self) -> &T { 951 | unsafe { 952 | &*self.reference 953 | } 954 | } 955 | } 956 | 957 | impl Deref for OwningRefMut { 958 | type Target = T; 959 | 960 | fn deref(&self) -> &T { 961 | unsafe { 962 | &*self.reference 963 | } 964 | } 965 | } 966 | 967 | impl DerefMut for OwningRefMut { 968 | fn deref_mut(&mut self) -> &mut T { 969 | unsafe { 970 | &mut *self.reference 971 | } 972 | } 973 | } 974 | 975 | unsafe impl StableAddress for OwningRef {} 976 | 977 | unsafe impl StableAddress for OwningRefMut {} 978 | 979 | impl AsRef for OwningRef { 980 | fn as_ref(&self) -> &T { 981 | &*self 982 | } 983 | } 984 | 985 | impl AsRef for OwningRefMut { 986 | fn as_ref(&self) -> &T { 987 | &*self 988 | } 989 | } 990 | 991 | impl AsMut for OwningRefMut { 992 | fn as_mut(&mut self) -> &mut T { 993 | &mut *self 994 | } 995 | } 996 | 997 | impl Borrow for OwningRef { 998 | fn borrow(&self) -> &T { 999 | &*self 1000 | } 1001 | } 1002 | 1003 | impl From for OwningRef 1004 | where O: StableAddress, 1005 | O: Deref, 1006 | { 1007 | fn from(owner: O) -> Self { 1008 | OwningRef::new(owner) 1009 | } 1010 | } 1011 | 1012 | impl From for OwningRefMut 1013 | where O: StableAddress, 1014 | O: DerefMut 1015 | { 1016 | fn from(owner: O) -> Self { 1017 | OwningRefMut::new(owner) 1018 | } 1019 | } 1020 | 1021 | impl From> for OwningRef 1022 | where O: StableAddress, 1023 | O: DerefMut 1024 | { 1025 | fn from(other: OwningRefMut) -> Self { 1026 | OwningRef { 1027 | owner: other.owner, 1028 | reference: other.reference, 1029 | } 1030 | } 1031 | } 1032 | 1033 | // ^ FIXME: Is a Into impl for calling into_owner() possible as well? 1034 | 1035 | impl Debug for OwningRef 1036 | where O: Debug, 1037 | T: Debug, 1038 | { 1039 | fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { 1040 | write!(f, 1041 | "OwningRef {{ owner: {:?}, reference: {:?} }}", 1042 | self.as_owner(), 1043 | &**self) 1044 | } 1045 | } 1046 | 1047 | impl Debug for OwningRefMut 1048 | where O: Debug, 1049 | T: Debug, 1050 | { 1051 | fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { 1052 | write!(f, 1053 | "OwningRefMut {{ owner: {:?}, reference: {:?} }}", 1054 | self.as_owner(), 1055 | &**self) 1056 | } 1057 | } 1058 | 1059 | impl Clone for OwningRef 1060 | where O: CloneStableAddress, 1061 | { 1062 | fn clone(&self) -> Self { 1063 | OwningRef { 1064 | owner: self.owner.clone(), 1065 | reference: self.reference, 1066 | } 1067 | } 1068 | } 1069 | 1070 | unsafe impl CloneStableAddress for OwningRef 1071 | where O: CloneStableAddress {} 1072 | 1073 | unsafe impl Send for OwningRef 1074 | where O: Send, for<'a> (&'a T): Send {} 1075 | unsafe impl Sync for OwningRef 1076 | where O: Sync, for<'a> (&'a T): Sync {} 1077 | 1078 | unsafe impl Send for OwningRefMut 1079 | where O: Send, for<'a> (&'a mut T): Send {} 1080 | unsafe impl Sync for OwningRefMut 1081 | where O: Sync, for<'a> (&'a mut T): Sync {} 1082 | 1083 | impl Debug for dyn Erased { 1084 | fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { 1085 | write!(f, "",) 1086 | } 1087 | } 1088 | 1089 | impl PartialEq for OwningRef where T: PartialEq { 1090 | fn eq(&self, other: &Self) -> bool { 1091 | (&*self as &T).eq(&*other as &T) 1092 | } 1093 | } 1094 | 1095 | impl Eq for OwningRef where T: Eq {} 1096 | 1097 | impl PartialOrd for OwningRef where T: PartialOrd { 1098 | fn partial_cmp(&self, other: &Self) -> Option { 1099 | (&*self as &T).partial_cmp(&*other as &T) 1100 | } 1101 | } 1102 | 1103 | impl Ord for OwningRef where T: Ord { 1104 | fn cmp(&self, other: &Self) -> Ordering { 1105 | (&*self as &T).cmp(&*other as &T) 1106 | } 1107 | } 1108 | 1109 | impl Hash for OwningRef where T: Hash { 1110 | fn hash(&self, state: &mut H) { 1111 | (&*self as &T).hash(state); 1112 | } 1113 | } 1114 | 1115 | impl PartialEq for OwningRefMut where T: PartialEq { 1116 | fn eq(&self, other: &Self) -> bool { 1117 | (&*self as &T).eq(&*other as &T) 1118 | } 1119 | } 1120 | 1121 | impl Eq for OwningRefMut where T: Eq {} 1122 | 1123 | impl PartialOrd for OwningRefMut where T: PartialOrd { 1124 | fn partial_cmp(&self, other: &Self) -> Option { 1125 | (&*self as &T).partial_cmp(&*other as &T) 1126 | } 1127 | } 1128 | 1129 | impl Ord for OwningRefMut where T: Ord { 1130 | fn cmp(&self, other: &Self) -> Ordering { 1131 | (&*self as &T).cmp(&*other as &T) 1132 | } 1133 | } 1134 | 1135 | impl Hash for OwningRefMut where T: Hash { 1136 | fn hash(&self, state: &mut H) { 1137 | (&*self as &T).hash(state); 1138 | } 1139 | } 1140 | 1141 | ///////////////////////////////////////////////////////////////////////////// 1142 | // std types integration and convenience type defs 1143 | ///////////////////////////////////////////////////////////////////////////// 1144 | 1145 | use std::boxed::Box; 1146 | use std::rc::Rc; 1147 | use std::sync::Arc; 1148 | use std::sync::{MutexGuard, RwLockReadGuard, RwLockWriteGuard}; 1149 | use std::cell::{Ref, RefCell, RefMut}; 1150 | 1151 | impl ToHandle for RefCell { 1152 | type Handle = Ref<'static, T>; 1153 | unsafe fn to_handle(x: *const Self) -> Self::Handle { (*x).borrow() } 1154 | } 1155 | 1156 | impl ToHandleMut for RefCell { 1157 | type HandleMut = RefMut<'static, T>; 1158 | unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut { (*x).borrow_mut() } 1159 | } 1160 | 1161 | // NB: Implementing ToHandle{,Mut} for Mutex and RwLock requires a decision 1162 | // about which handle creation to use (i.e. read() vs try_read()) as well as 1163 | // what to do with error results. 1164 | 1165 | /// Typedef of a owning reference that uses a `Box` as the owner. 1166 | pub type BoxRef = OwningRef, U>; 1167 | /// Typedef of a owning reference that uses a `Vec` as the owner. 1168 | pub type VecRef = OwningRef, U>; 1169 | /// Typedef of a owning reference that uses a `String` as the owner. 1170 | pub type StringRef = OwningRef; 1171 | 1172 | /// Typedef of a owning reference that uses a `Rc` as the owner. 1173 | pub type RcRef = OwningRef, U>; 1174 | /// Typedef of a owning reference that uses a `Arc` as the owner. 1175 | pub type ArcRef = OwningRef, U>; 1176 | 1177 | /// Typedef of a owning reference that uses a `Ref` as the owner. 1178 | pub type RefRef<'a, T, U = T> = OwningRef, U>; 1179 | /// Typedef of a owning reference that uses a `RefMut` as the owner. 1180 | pub type RefMutRef<'a, T, U = T> = OwningRef, U>; 1181 | /// Typedef of a owning reference that uses a `MutexGuard` as the owner. 1182 | pub type MutexGuardRef<'a, T, U = T> = OwningRef, U>; 1183 | /// Typedef of a owning reference that uses a `RwLockReadGuard` as the owner. 1184 | pub type RwLockReadGuardRef<'a, T, U = T> = OwningRef, U>; 1185 | /// Typedef of a owning reference that uses a `RwLockWriteGuard` as the owner. 1186 | pub type RwLockWriteGuardRef<'a, T, U = T> = OwningRef, U>; 1187 | 1188 | /// Typedef of a mutable owning reference that uses a `Box` as the owner. 1189 | pub type BoxRefMut = OwningRefMut, U>; 1190 | /// Typedef of a mutable owning reference that uses a `Vec` as the owner. 1191 | pub type VecRefMut = OwningRefMut, U>; 1192 | /// Typedef of a mutable owning reference that uses a `String` as the owner. 1193 | pub type StringRefMut = OwningRefMut; 1194 | 1195 | /// Typedef of a mutable owning reference that uses a `RefMut` as the owner. 1196 | pub type RefMutRefMut<'a, T, U = T> = OwningRefMut, U>; 1197 | /// Typedef of a mutable owning reference that uses a `MutexGuard` as the owner. 1198 | pub type MutexGuardRefMut<'a, T, U = T> = OwningRefMut, U>; 1199 | /// Typedef of a mutable owning reference that uses a `RwLockWriteGuard` as the owner. 1200 | pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRefMut, U>; 1201 | 1202 | unsafe impl<'a, T: 'a> IntoErased<'a> for Box { 1203 | type Erased = Box; 1204 | fn into_erased(self) -> Self::Erased { 1205 | self 1206 | } 1207 | } 1208 | unsafe impl<'a, T: 'a> IntoErased<'a> for Rc { 1209 | type Erased = Rc; 1210 | fn into_erased(self) -> Self::Erased { 1211 | self 1212 | } 1213 | } 1214 | unsafe impl<'a, T: 'a> IntoErased<'a> for Arc { 1215 | type Erased = Arc; 1216 | fn into_erased(self) -> Self::Erased { 1217 | self 1218 | } 1219 | } 1220 | 1221 | /// Typedef of a owning reference that uses an erased `Box` as the owner. 1222 | pub type ErasedBoxRef = OwningRef, U>; 1223 | /// Typedef of a owning reference that uses an erased `Rc` as the owner. 1224 | pub type ErasedRcRef = OwningRef, U>; 1225 | /// Typedef of a owning reference that uses an erased `Arc` as the owner. 1226 | pub type ErasedArcRef = OwningRef, U>; 1227 | 1228 | /// Typedef of a mutable owning reference that uses an erased `Box` as the owner. 1229 | pub type ErasedBoxRefMut = OwningRefMut, U>; 1230 | 1231 | #[cfg(test)] 1232 | mod tests { 1233 | mod owning_ref { 1234 | use super::super::OwningRef; 1235 | use super::super::{RcRef, BoxRef, Erased, ErasedBoxRef}; 1236 | use std::cmp::{PartialEq, Ord, PartialOrd, Ordering}; 1237 | use std::hash::{Hash, Hasher}; 1238 | use std::collections::hash_map::DefaultHasher; 1239 | use std::collections::HashMap; 1240 | use std::rc::Rc; 1241 | 1242 | #[derive(Debug, PartialEq)] 1243 | struct Example(u32, String, [u8; 3]); 1244 | fn example() -> Example { 1245 | Example(42, "hello world".to_string(), [1, 2, 3]) 1246 | } 1247 | 1248 | #[test] 1249 | fn new_deref() { 1250 | let or: OwningRef, ()> = OwningRef::new(Box::new(())); 1251 | assert_eq!(&*or, &()); 1252 | } 1253 | 1254 | #[test] 1255 | fn into() { 1256 | let or: OwningRef, ()> = Box::new(()).into(); 1257 | assert_eq!(&*or, &()); 1258 | } 1259 | 1260 | #[test] 1261 | fn map_offset_ref() { 1262 | let or: BoxRef = Box::new(example()).into(); 1263 | let or: BoxRef<_, u32> = or.map(|x| &x.0); 1264 | assert_eq!(&*or, &42); 1265 | 1266 | let or: BoxRef = Box::new(example()).into(); 1267 | let or: BoxRef<_, u8> = or.map(|x| &x.2[1]); 1268 | assert_eq!(&*or, &2); 1269 | } 1270 | 1271 | #[test] 1272 | fn map_heap_ref() { 1273 | let or: BoxRef = Box::new(example()).into(); 1274 | let or: BoxRef<_, str> = or.map(|x| &x.1[..5]); 1275 | assert_eq!(&*or, "hello"); 1276 | } 1277 | 1278 | #[test] 1279 | fn map_static_ref() { 1280 | let or: BoxRef<()> = Box::new(()).into(); 1281 | let or: BoxRef<_, str> = or.map(|_| "hello"); 1282 | assert_eq!(&*or, "hello"); 1283 | } 1284 | 1285 | #[test] 1286 | fn map_chained() { 1287 | let or: BoxRef = Box::new(example().1).into(); 1288 | let or: BoxRef<_, str> = or.map(|x| &x[1..5]); 1289 | let or: BoxRef<_, str> = or.map(|x| &x[..2]); 1290 | assert_eq!(&*or, "el"); 1291 | } 1292 | 1293 | #[test] 1294 | fn map_chained_inference() { 1295 | let or = BoxRef::new(Box::new(example().1)) 1296 | .map(|x| &x[..5]) 1297 | .map(|x| &x[1..3]); 1298 | assert_eq!(&*or, "el"); 1299 | } 1300 | 1301 | #[test] 1302 | fn as_owner() { 1303 | let or: BoxRef = Box::new(example().1).into(); 1304 | let or = or.map(|x| &x[..5]); 1305 | assert_eq!(&*or, "hello"); 1306 | assert_eq!(&**or.as_owner(), "hello world"); 1307 | } 1308 | 1309 | #[test] 1310 | fn into_owner() { 1311 | let or: BoxRef = Box::new(example().1).into(); 1312 | let or = or.map(|x| &x[..5]); 1313 | assert_eq!(&*or, "hello"); 1314 | let s = *or.into_owner(); 1315 | assert_eq!(&s, "hello world"); 1316 | } 1317 | 1318 | #[test] 1319 | fn fmt_debug() { 1320 | let or: BoxRef = Box::new(example().1).into(); 1321 | let or = or.map(|x| &x[..5]); 1322 | let s = format!("{:?}", or); 1323 | assert_eq!(&s, "OwningRef { owner: \"hello world\", reference: \"hello\" }"); 1324 | } 1325 | 1326 | #[test] 1327 | fn erased_owner() { 1328 | let o1: BoxRef = BoxRef::new(Box::new(example())) 1329 | .map(|x| &x.1[..]); 1330 | 1331 | let o2: BoxRef = BoxRef::new(Box::new(example().1)) 1332 | .map(|x| &x[..]); 1333 | 1334 | let os: Vec> = vec![o1.erase_owner(), o2.erase_owner()]; 1335 | assert!(os.iter().all(|e| &e[..] == "hello world")); 1336 | } 1337 | 1338 | #[test] 1339 | fn non_static_erased_owner() { 1340 | let foo = [413, 612]; 1341 | let bar = &foo; 1342 | 1343 | // FIXME: lifetime inference fails us, and we can't easily define a lifetime for a closure 1344 | // (see https://github.com/rust-lang/rust/issues/22340) 1345 | // So we use a function to identify the lifetimes instead. 1346 | fn borrow<'a>(a: &'a &[i32; 2]) -> &'a i32 { 1347 | &a[0] 1348 | } 1349 | 1350 | let o: BoxRef<&[i32; 2]> = Box::new(bar).into(); 1351 | let o: BoxRef<&[i32; 2], i32> = o.map(borrow); 1352 | let o: BoxRef = o.erase_owner(); 1353 | 1354 | assert_eq!(*o, 413); 1355 | } 1356 | 1357 | #[test] 1358 | fn raii_locks() { 1359 | use super::super::{RefRef, RefMutRef}; 1360 | use std::cell::RefCell; 1361 | use super::super::{MutexGuardRef, RwLockReadGuardRef, RwLockWriteGuardRef}; 1362 | use std::sync::{Mutex, RwLock}; 1363 | 1364 | { 1365 | let a = RefCell::new(1); 1366 | let a = { 1367 | let a = RefRef::new(a.borrow()); 1368 | assert_eq!(*a, 1); 1369 | a 1370 | }; 1371 | assert_eq!(*a, 1); 1372 | drop(a); 1373 | } 1374 | { 1375 | let a = RefCell::new(1); 1376 | let a = { 1377 | let a = RefMutRef::new(a.borrow_mut()); 1378 | assert_eq!(*a, 1); 1379 | a 1380 | }; 1381 | assert_eq!(*a, 1); 1382 | drop(a); 1383 | } 1384 | { 1385 | let a = Mutex::new(1); 1386 | let a = { 1387 | let a = MutexGuardRef::new(a.lock().unwrap()); 1388 | assert_eq!(*a, 1); 1389 | a 1390 | }; 1391 | assert_eq!(*a, 1); 1392 | drop(a); 1393 | } 1394 | { 1395 | let a = RwLock::new(1); 1396 | let a = { 1397 | let a = RwLockReadGuardRef::new(a.read().unwrap()); 1398 | assert_eq!(*a, 1); 1399 | a 1400 | }; 1401 | assert_eq!(*a, 1); 1402 | drop(a); 1403 | } 1404 | { 1405 | let a = RwLock::new(1); 1406 | let a = { 1407 | let a = RwLockWriteGuardRef::new(a.write().unwrap()); 1408 | assert_eq!(*a, 1); 1409 | a 1410 | }; 1411 | assert_eq!(*a, 1); 1412 | drop(a); 1413 | } 1414 | } 1415 | 1416 | #[test] 1417 | fn eq() { 1418 | let or1: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice()); 1419 | let or2: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice()); 1420 | assert_eq!(or1.eq(&or2), true); 1421 | } 1422 | 1423 | #[test] 1424 | fn cmp() { 1425 | let or1: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice()); 1426 | let or2: BoxRef<[u8]> = BoxRef::new(vec![4, 5, 6].into_boxed_slice()); 1427 | assert_eq!(or1.cmp(&or2), Ordering::Less); 1428 | } 1429 | 1430 | #[test] 1431 | fn partial_cmp() { 1432 | let or1: BoxRef<[u8]> = BoxRef::new(vec![4, 5, 6].into_boxed_slice()); 1433 | let or2: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice()); 1434 | assert_eq!(or1.partial_cmp(&or2), Some(Ordering::Greater)); 1435 | } 1436 | 1437 | #[test] 1438 | fn hash() { 1439 | let mut h1 = DefaultHasher::new(); 1440 | let mut h2 = DefaultHasher::new(); 1441 | 1442 | let or1: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice()); 1443 | let or2: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice()); 1444 | 1445 | or1.hash(&mut h1); 1446 | or2.hash(&mut h2); 1447 | 1448 | assert_eq!(h1.finish(), h2.finish()); 1449 | } 1450 | 1451 | #[test] 1452 | fn borrow() { 1453 | let mut hash = HashMap::new(); 1454 | let key = RcRef::::new(Rc::new("foo-bar".to_string())).map(|s| &s[..]); 1455 | 1456 | hash.insert(key.clone().map(|s| &s[..3]), 42); 1457 | hash.insert(key.clone().map(|s| &s[4..]), 23); 1458 | 1459 | assert_eq!(hash.get("foo"), Some(&42)); 1460 | assert_eq!(hash.get("bar"), Some(&23)); 1461 | } 1462 | 1463 | #[test] 1464 | fn total_erase() { 1465 | let a: OwningRef, [u8]> 1466 | = OwningRef::new(vec![]).map(|x| &x[..]); 1467 | let b: OwningRef, [u8]> 1468 | = OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]); 1469 | 1470 | let c: OwningRef>, [u8]> = unsafe {a.map_owner(Rc::new)}; 1471 | let d: OwningRef>, [u8]> = unsafe {b.map_owner(Rc::new)}; 1472 | 1473 | let e: OwningRef, [u8]> = c.erase_owner(); 1474 | let f: OwningRef, [u8]> = d.erase_owner(); 1475 | 1476 | let _g = e.clone(); 1477 | let _h = f.clone(); 1478 | } 1479 | 1480 | #[test] 1481 | fn total_erase_box() { 1482 | let a: OwningRef, [u8]> 1483 | = OwningRef::new(vec![]).map(|x| &x[..]); 1484 | let b: OwningRef, [u8]> 1485 | = OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]); 1486 | 1487 | let c: OwningRef>, [u8]> = a.map_owner_box(); 1488 | let d: OwningRef>, [u8]> = b.map_owner_box(); 1489 | 1490 | let _e: OwningRef, [u8]> = c.erase_owner(); 1491 | let _f: OwningRef, [u8]> = d.erase_owner(); 1492 | } 1493 | 1494 | #[test] 1495 | fn try_map1() { 1496 | use std::any::Any; 1497 | 1498 | let x = Box::new(123_i32); 1499 | let y: Box = x; 1500 | 1501 | OwningRef::new(y).try_map(|x| x.downcast_ref::().ok_or(())).unwrap(); 1502 | } 1503 | 1504 | #[test] 1505 | fn try_map2() { 1506 | use std::any::Any; 1507 | 1508 | let x = Box::new(123_u32); 1509 | let y: Box = x; 1510 | 1511 | OwningRef::new(y).try_map(|x| x.downcast_ref::().ok_or(())).unwrap_err(); 1512 | } 1513 | 1514 | #[test] 1515 | fn map_with_owner() { 1516 | let owning_ref: BoxRef = Box::new(example()).into(); 1517 | let owning_ref = owning_ref.map(|owner| &owner.1); 1518 | 1519 | owning_ref.map_with_owner(|owner, ref_field| { 1520 | assert_eq!(owner.1, *ref_field); 1521 | ref_field 1522 | }); 1523 | } 1524 | 1525 | #[test] 1526 | fn try_map_with_owner_ok() { 1527 | let owning_ref: BoxRef = Box::new(example()).into(); 1528 | let owning_ref = owning_ref.map(|owner| &owner.1); 1529 | 1530 | owning_ref.try_map_with_owner(|owner, ref_field| { 1531 | assert_eq!(owner.1, *ref_field); 1532 | Ok(ref_field) as Result<_, ()> 1533 | }).unwrap(); 1534 | } 1535 | 1536 | #[test] 1537 | fn try_map_with_owner_err() { 1538 | let owning_ref: BoxRef = Box::new(example()).into(); 1539 | let owning_ref = owning_ref.map(|owner| &owner.1); 1540 | 1541 | owning_ref.try_map_with_owner(|owner, ref_field| { 1542 | assert_eq!(owner.1, *ref_field); 1543 | Err(()) as Result<&(), _> 1544 | }).unwrap_err(); 1545 | } 1546 | } 1547 | 1548 | mod owning_handle { 1549 | use super::super::OwningHandle; 1550 | use super::super::RcRef; 1551 | use std::rc::Rc; 1552 | use std::cell::RefCell; 1553 | use std::sync::Arc; 1554 | use std::sync::RwLock; 1555 | 1556 | #[test] 1557 | fn owning_handle() { 1558 | use std::cell::RefCell; 1559 | let cell = Rc::new(RefCell::new(2)); 1560 | let cell_ref = RcRef::new(cell); 1561 | let mut handle = OwningHandle::new_with_fn(cell_ref, |x| unsafe { x.as_ref() }.unwrap().borrow_mut()); 1562 | assert_eq!(*handle, 2); 1563 | *handle = 3; 1564 | assert_eq!(*handle, 3); 1565 | } 1566 | 1567 | #[test] 1568 | fn try_owning_handle_ok() { 1569 | use std::cell::RefCell; 1570 | let cell = Rc::new(RefCell::new(2)); 1571 | let cell_ref = RcRef::new(cell); 1572 | let mut handle = OwningHandle::try_new::<_, ()>(cell_ref, |x| { 1573 | Ok(unsafe { 1574 | x.as_ref() 1575 | }.unwrap().borrow_mut()) 1576 | }).unwrap(); 1577 | assert_eq!(*handle, 2); 1578 | *handle = 3; 1579 | assert_eq!(*handle, 3); 1580 | } 1581 | 1582 | #[test] 1583 | fn try_owning_handle_err() { 1584 | use std::cell::RefCell; 1585 | let cell = Rc::new(RefCell::new(2)); 1586 | let cell_ref = RcRef::new(cell); 1587 | let handle = OwningHandle::try_new::<_, ()>(cell_ref, |x| { 1588 | if false { 1589 | return Ok(unsafe { 1590 | x.as_ref() 1591 | }.unwrap().borrow_mut()) 1592 | } 1593 | Err(()) 1594 | }); 1595 | assert!(handle.is_err()); 1596 | } 1597 | 1598 | #[test] 1599 | fn nested() { 1600 | use std::cell::RefCell; 1601 | use std::sync::{Arc, RwLock}; 1602 | 1603 | let result = { 1604 | let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString")))); 1605 | let curr = RcRef::new(complex); 1606 | let curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut()); 1607 | let mut curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().try_write().unwrap()); 1608 | assert_eq!(*curr, "someString"); 1609 | *curr = "someOtherString"; 1610 | curr 1611 | }; 1612 | assert_eq!(*result, "someOtherString"); 1613 | } 1614 | 1615 | #[test] 1616 | fn owning_handle_safe() { 1617 | use std::cell::RefCell; 1618 | let cell = Rc::new(RefCell::new(2)); 1619 | let cell_ref = RcRef::new(cell); 1620 | let handle = OwningHandle::new(cell_ref); 1621 | assert_eq!(*handle, 2); 1622 | } 1623 | 1624 | #[test] 1625 | fn owning_handle_mut_safe() { 1626 | use std::cell::RefCell; 1627 | let cell = Rc::new(RefCell::new(2)); 1628 | let cell_ref = RcRef::new(cell); 1629 | let mut handle = OwningHandle::new_mut(cell_ref); 1630 | assert_eq!(*handle, 2); 1631 | *handle = 3; 1632 | assert_eq!(*handle, 3); 1633 | } 1634 | 1635 | #[test] 1636 | fn owning_handle_safe_2() { 1637 | let result = { 1638 | let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString")))); 1639 | let curr = RcRef::new(complex); 1640 | let curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut()); 1641 | let mut curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().try_write().unwrap()); 1642 | assert_eq!(*curr, "someString"); 1643 | *curr = "someOtherString"; 1644 | curr 1645 | }; 1646 | assert_eq!(*result, "someOtherString"); 1647 | } 1648 | } 1649 | 1650 | mod owning_ref_mut { 1651 | use super::super::{OwningRefMut, BoxRefMut, Erased, ErasedBoxRefMut}; 1652 | use super::super::BoxRef; 1653 | use std::cmp::{PartialEq, Ord, PartialOrd, Ordering}; 1654 | use std::hash::{Hash, Hasher}; 1655 | use std::collections::hash_map::DefaultHasher; 1656 | use std::collections::HashMap; 1657 | 1658 | #[derive(Debug, PartialEq)] 1659 | struct Example(u32, String, [u8; 3]); 1660 | fn example() -> Example { 1661 | Example(42, "hello world".to_string(), [1, 2, 3]) 1662 | } 1663 | 1664 | #[test] 1665 | fn new_deref() { 1666 | let or: OwningRefMut, ()> = OwningRefMut::new(Box::new(())); 1667 | assert_eq!(&*or, &()); 1668 | } 1669 | 1670 | #[test] 1671 | fn new_deref_mut() { 1672 | let mut or: OwningRefMut, ()> = OwningRefMut::new(Box::new(())); 1673 | assert_eq!(&mut *or, &mut ()); 1674 | } 1675 | 1676 | #[test] 1677 | fn mutate() { 1678 | let mut or: OwningRefMut, usize> = OwningRefMut::new(Box::new(0)); 1679 | assert_eq!(&*or, &0); 1680 | *or = 1; 1681 | assert_eq!(&*or, &1); 1682 | } 1683 | 1684 | #[test] 1685 | fn into() { 1686 | let or: OwningRefMut, ()> = Box::new(()).into(); 1687 | assert_eq!(&*or, &()); 1688 | } 1689 | 1690 | #[test] 1691 | fn map_offset_ref() { 1692 | let or: BoxRefMut = Box::new(example()).into(); 1693 | let or: BoxRef<_, u32> = or.map(|x| &mut x.0); 1694 | assert_eq!(&*or, &42); 1695 | 1696 | let or: BoxRefMut = Box::new(example()).into(); 1697 | let or: BoxRef<_, u8> = or.map(|x| &mut x.2[1]); 1698 | assert_eq!(&*or, &2); 1699 | } 1700 | 1701 | #[test] 1702 | fn map_heap_ref() { 1703 | let or: BoxRefMut = Box::new(example()).into(); 1704 | let or: BoxRef<_, str> = or.map(|x| &mut x.1[..5]); 1705 | assert_eq!(&*or, "hello"); 1706 | } 1707 | 1708 | #[test] 1709 | fn map_static_ref() { 1710 | let or: BoxRefMut<()> = Box::new(()).into(); 1711 | let or: BoxRef<_, str> = or.map(|_| "hello"); 1712 | assert_eq!(&*or, "hello"); 1713 | } 1714 | 1715 | #[test] 1716 | fn map_mut_offset_ref() { 1717 | let or: BoxRefMut = Box::new(example()).into(); 1718 | let or: BoxRefMut<_, u32> = or.map_mut(|x| &mut x.0); 1719 | assert_eq!(&*or, &42); 1720 | 1721 | let or: BoxRefMut = Box::new(example()).into(); 1722 | let or: BoxRefMut<_, u8> = or.map_mut(|x| &mut x.2[1]); 1723 | assert_eq!(&*or, &2); 1724 | } 1725 | 1726 | #[test] 1727 | fn map_mut_heap_ref() { 1728 | let or: BoxRefMut = Box::new(example()).into(); 1729 | let or: BoxRefMut<_, str> = or.map_mut(|x| &mut x.1[..5]); 1730 | assert_eq!(&*or, "hello"); 1731 | } 1732 | 1733 | #[test] 1734 | fn map_mut_static_ref() { 1735 | static mut MUT_S: [u8; 5] = *b"hello"; 1736 | 1737 | let mut_s: &'static mut [u8] = unsafe { &mut MUT_S }; 1738 | 1739 | let or: BoxRefMut<()> = Box::new(()).into(); 1740 | let or: BoxRefMut<_, [u8]> = or.map_mut(move |_| mut_s); 1741 | assert_eq!(&*or, b"hello"); 1742 | } 1743 | 1744 | #[test] 1745 | fn map_mut_chained() { 1746 | let or: BoxRefMut = Box::new(example().1).into(); 1747 | let or: BoxRefMut<_, str> = or.map_mut(|x| &mut x[1..5]); 1748 | let or: BoxRefMut<_, str> = or.map_mut(|x| &mut x[..2]); 1749 | assert_eq!(&*or, "el"); 1750 | } 1751 | 1752 | #[test] 1753 | fn map_chained_inference() { 1754 | let or = BoxRefMut::new(Box::new(example().1)) 1755 | .map_mut(|x| &mut x[..5]) 1756 | .map_mut(|x| &mut x[1..3]); 1757 | assert_eq!(&*or, "el"); 1758 | } 1759 | 1760 | #[test] 1761 | fn try_map_mut() { 1762 | let or: BoxRefMut = Box::new(example().1).into(); 1763 | let or: Result, ()> = or.try_map_mut(|x| Ok(&mut x[1..5])); 1764 | assert_eq!(&*or.unwrap(), "ello"); 1765 | 1766 | let or: BoxRefMut = Box::new(example().1).into(); 1767 | let or: Result, ()> = or.try_map_mut(|_| Err(())); 1768 | assert!(or.is_err()); 1769 | } 1770 | 1771 | #[test] 1772 | fn as_owner() { 1773 | let or: BoxRefMut = Box::new(example().1).into(); 1774 | let or = or.map_mut(|x| &mut x[..5]); 1775 | assert_eq!(&*or, "hello"); 1776 | assert_eq!(&**or.as_owner(), "hello world"); 1777 | } 1778 | 1779 | #[test] 1780 | fn into_owner() { 1781 | let or: BoxRefMut = Box::new(example().1).into(); 1782 | let or = or.map_mut(|x| &mut x[..5]); 1783 | assert_eq!(&*or, "hello"); 1784 | let s = *or.into_owner(); 1785 | assert_eq!(&s, "hello world"); 1786 | } 1787 | 1788 | #[test] 1789 | fn fmt_debug() { 1790 | let or: BoxRefMut = Box::new(example().1).into(); 1791 | let or = or.map_mut(|x| &mut x[..5]); 1792 | let s = format!("{:?}", or); 1793 | assert_eq!(&s, 1794 | "OwningRefMut { owner: \"hello world\", reference: \"hello\" }"); 1795 | } 1796 | 1797 | #[test] 1798 | fn erased_owner() { 1799 | let o1: BoxRefMut = BoxRefMut::new(Box::new(example())) 1800 | .map_mut(|x| &mut x.1[..]); 1801 | 1802 | let o2: BoxRefMut = BoxRefMut::new(Box::new(example().1)) 1803 | .map_mut(|x| &mut x[..]); 1804 | 1805 | let os: Vec> = vec![o1.erase_owner(), o2.erase_owner()]; 1806 | assert!(os.iter().all(|e| &e[..] == "hello world")); 1807 | } 1808 | 1809 | #[test] 1810 | fn non_static_erased_owner() { 1811 | let mut foo = [413, 612]; 1812 | let bar = &mut foo; 1813 | 1814 | // FIXME: lifetime inference fails us, and we can't easily define a lifetime for a closure 1815 | // (see https://github.com/rust-lang/rust/issues/22340) 1816 | // So we use a function to identify the lifetimes instead. 1817 | fn borrow<'a>(a: &'a mut &mut [i32; 2]) -> &'a mut i32 { 1818 | &mut a[0] 1819 | } 1820 | 1821 | let o: BoxRefMut<&mut [i32; 2]> = Box::new(bar).into(); 1822 | let o: BoxRefMut<&mut [i32; 2], i32> = o.map_mut(borrow); 1823 | let o: BoxRefMut = o.erase_owner(); 1824 | 1825 | assert_eq!(*o, 413); 1826 | } 1827 | 1828 | #[test] 1829 | fn raii_locks() { 1830 | use super::super::RefMutRefMut; 1831 | use std::cell::RefCell; 1832 | use super::super::{MutexGuardRefMut, RwLockWriteGuardRefMut}; 1833 | use std::sync::{Mutex, RwLock}; 1834 | 1835 | { 1836 | let a = RefCell::new(1); 1837 | let a = { 1838 | let a = RefMutRefMut::new(a.borrow_mut()); 1839 | assert_eq!(*a, 1); 1840 | a 1841 | }; 1842 | assert_eq!(*a, 1); 1843 | drop(a); 1844 | } 1845 | { 1846 | let a = Mutex::new(1); 1847 | let a = { 1848 | let a = MutexGuardRefMut::new(a.lock().unwrap()); 1849 | assert_eq!(*a, 1); 1850 | a 1851 | }; 1852 | assert_eq!(*a, 1); 1853 | drop(a); 1854 | } 1855 | { 1856 | let a = RwLock::new(1); 1857 | let a = { 1858 | let a = RwLockWriteGuardRefMut::new(a.write().unwrap()); 1859 | assert_eq!(*a, 1); 1860 | a 1861 | }; 1862 | assert_eq!(*a, 1); 1863 | drop(a); 1864 | } 1865 | } 1866 | 1867 | #[test] 1868 | fn eq() { 1869 | let or1: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice()); 1870 | let or2: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice()); 1871 | assert_eq!(or1.eq(&or2), true); 1872 | } 1873 | 1874 | #[test] 1875 | fn cmp() { 1876 | let or1: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice()); 1877 | let or2: BoxRefMut<[u8]> = BoxRefMut::new(vec![4, 5, 6].into_boxed_slice()); 1878 | assert_eq!(or1.cmp(&or2), Ordering::Less); 1879 | } 1880 | 1881 | #[test] 1882 | fn partial_cmp() { 1883 | let or1: BoxRefMut<[u8]> = BoxRefMut::new(vec![4, 5, 6].into_boxed_slice()); 1884 | let or2: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice()); 1885 | assert_eq!(or1.partial_cmp(&or2), Some(Ordering::Greater)); 1886 | } 1887 | 1888 | #[test] 1889 | fn hash() { 1890 | let mut h1 = DefaultHasher::new(); 1891 | let mut h2 = DefaultHasher::new(); 1892 | 1893 | let or1: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice()); 1894 | let or2: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice()); 1895 | 1896 | or1.hash(&mut h1); 1897 | or2.hash(&mut h2); 1898 | 1899 | assert_eq!(h1.finish(), h2.finish()); 1900 | } 1901 | 1902 | #[test] 1903 | fn borrow() { 1904 | let mut hash = HashMap::new(); 1905 | let key1 = BoxRefMut::::new(Box::new("foo".to_string())).map(|s| &s[..]); 1906 | let key2 = BoxRefMut::::new(Box::new("bar".to_string())).map(|s| &s[..]); 1907 | 1908 | hash.insert(key1, 42); 1909 | hash.insert(key2, 23); 1910 | 1911 | assert_eq!(hash.get("foo"), Some(&42)); 1912 | assert_eq!(hash.get("bar"), Some(&23)); 1913 | } 1914 | 1915 | #[test] 1916 | fn total_erase() { 1917 | let a: OwningRefMut, [u8]> 1918 | = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]); 1919 | let b: OwningRefMut, [u8]> 1920 | = OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]); 1921 | 1922 | let c: OwningRefMut>, [u8]> = unsafe {a.map_owner(Box::new)}; 1923 | let d: OwningRefMut>, [u8]> = unsafe {b.map_owner(Box::new)}; 1924 | 1925 | let _e: OwningRefMut, [u8]> = c.erase_owner(); 1926 | let _f: OwningRefMut, [u8]> = d.erase_owner(); 1927 | } 1928 | 1929 | #[test] 1930 | fn total_erase_box() { 1931 | let a: OwningRefMut, [u8]> 1932 | = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]); 1933 | let b: OwningRefMut, [u8]> 1934 | = OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]); 1935 | 1936 | let c: OwningRefMut>, [u8]> = a.map_owner_box(); 1937 | let d: OwningRefMut>, [u8]> = b.map_owner_box(); 1938 | 1939 | let _e: OwningRefMut, [u8]> = c.erase_owner(); 1940 | let _f: OwningRefMut, [u8]> = d.erase_owner(); 1941 | } 1942 | 1943 | #[test] 1944 | fn try_map1() { 1945 | use std::any::Any; 1946 | 1947 | let x = Box::new(123_i32); 1948 | let y: Box = x; 1949 | 1950 | OwningRefMut::new(y).try_map_mut(|x| x.downcast_mut::().ok_or(())).unwrap(); 1951 | } 1952 | 1953 | #[test] 1954 | fn try_map2() { 1955 | use std::any::Any; 1956 | 1957 | let x = Box::new(123_u32); 1958 | let y: Box = x; 1959 | 1960 | OwningRefMut::new(y).try_map_mut(|x| x.downcast_mut::().ok_or(())).unwrap_err(); 1961 | } 1962 | 1963 | #[test] 1964 | fn try_map3() { 1965 | use std::any::Any; 1966 | 1967 | let x = Box::new(123_i32); 1968 | let y: Box = x; 1969 | 1970 | OwningRefMut::new(y).try_map(|x| x.downcast_ref::().ok_or(())).unwrap(); 1971 | } 1972 | 1973 | #[test] 1974 | fn try_map4() { 1975 | use std::any::Any; 1976 | 1977 | let x = Box::new(123_u32); 1978 | let y: Box = x; 1979 | 1980 | OwningRefMut::new(y).try_map(|x| x.downcast_ref::().ok_or(())).unwrap_err(); 1981 | } 1982 | 1983 | #[test] 1984 | fn into_owning_ref() { 1985 | use super::super::BoxRef; 1986 | 1987 | let or: BoxRefMut<()> = Box::new(()).into(); 1988 | let or: BoxRef<()> = or.into(); 1989 | assert_eq!(&*or, &()); 1990 | } 1991 | 1992 | struct Foo { 1993 | u: u32, 1994 | } 1995 | struct Bar { 1996 | f: Foo, 1997 | } 1998 | 1999 | #[test] 2000 | fn ref_mut() { 2001 | use std::cell::RefCell; 2002 | 2003 | let a = RefCell::new(Bar { f: Foo { u: 42 } }); 2004 | let mut b = OwningRefMut::new(a.borrow_mut()); 2005 | assert_eq!(b.f.u, 42); 2006 | b.f.u = 43; 2007 | let mut c = b.map_mut(|x| &mut x.f); 2008 | assert_eq!(c.u, 43); 2009 | c.u = 44; 2010 | let mut d = c.map_mut(|x| &mut x.u); 2011 | assert_eq!(*d, 44); 2012 | *d = 45; 2013 | assert_eq!(*d, 45); 2014 | } 2015 | } 2016 | } 2017 | --------------------------------------------------------------------------------