xref: /linux/rust/pin-init/examples/selfref.rs (revision 12d5fc96ebbb3b948861805b32a4c3a96105ccd9)
1 // SPDX-License-Identifier: Apache-2.0 OR MIT
2 
3 #![allow(clippy::disallowed_names)]
4 
5 use pin_init::*;
6 
7 #[pin_data]
8 struct SelfRef {
9     #[uses('_: invariant)]
10     not_cov: Box<dyn Fn(&'str str) -> bool + 'str>,
11 
12     part: &'str str,
13     str: String,
14 
15     mut_part: &'mut_str mut str,
16     #[borrowed(mut)]
17     mut_str: String,
18 }
19 
20 fn use_self_ref() {
21     stack_pin_init!(let foo = pin_init!(SelfRef {
22         str: "hello world".to_owned(),
23         part: &str[..5],
24         mut_str: "hello world".to_owned(),
25         mut_part: &mut mut_str[..5],
26         not_cov: Box::new(move |s| s == str),
27     }));
28 
29     // Access via projection.
30     println!("{}", foo.as_mut().project().part);
31 
32     // Access via accessor.
33     println!("{}", foo.part());
34 
35     // Access via `with_project`, gives mutable reference.
36     foo.as_mut().with_project(|proj| {
37         *proj.part = &proj.str[5..];
38     });
39 
40     println!("{}", foo.part());
41 
42     // Access fields that mutable borrow others are similar to those of shared borrow.
43     println!("{}", foo.as_mut().project().mut_part);
44     println!("{}", foo.mut_part());
45     foo.as_mut().with_project(|proj| {
46         proj.mut_part.make_ascii_uppercase();
47     });
48 
49     // Access non-covariant type using `with_` accessor.
50     foo.with_not_cov(|not_cov| {
51         not_cov("");
52     });
53 
54     // Access non-covariant type using `with_project`.
55     foo.as_mut().with_project(|proj| (proj.not_cov)(proj.str));
56 }
57 
58 fn main() {
59     use_self_ref();
60 }
61