1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92use crate::error::*;
use crate::provide_any::{self, Demand, Provider};
// A concrete error type implemented by an application or library author.
#[derive(Debug)]
pub struct ConcreteError {
name: String,
array: Vec<String>,
}
impl Error for ConcreteError {
fn provide_context<'a>(&'a self, req: &mut Demand<'a>) {
// Provide a `String` value (a temporary value), a `&str` reference (references a field
// of `self`), and a slice of `String`s.
req.provide_value::<String, _>(|| "Hello!".to_owned())
.provide_value::<Vec<String>, _>(|| self.array.clone())
.provide_ref::<str>(&*self.name)
.provide_ref::<[String]>(&*self.array);
}
}
#[test]
fn access_context() {
let e: &dyn Error = &mut ConcreteError {
name: "Bob".to_owned(),
array: vec!["Alice".to_owned()],
};
// Get context by value.
let s: String = e.get_context().unwrap();
assert_eq!(&s, "Hello!");
// Get context by reference.
let s: &[String] = e.get_context_ref().unwrap();
assert_eq!(s, &*vec!["Alice".to_owned()]);
let s: &str = e.get_context_ref().unwrap();
assert_eq!(s, "Bob");
let v: Vec<String> = e.get_context().unwrap();
assert_eq!(v, vec!["Alice".to_owned()]);
}
// Implement Provider from a non-core crate.
// Also demonstrates use of mutable references.
trait Foo: Provider {}
impl dyn Foo {
pub fn get_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
provide_any::request_ref(self)
}
pub fn get_mut<T: ?Sized + 'static>(&mut self) -> Option<&mut T> {
provide_any::request_mut(self)
}
}
struct Bar {
s: String,
}
impl Foo for Bar {}
impl Provider for Bar {
fn provide<'a>(&'a self, req: &mut Demand<'a>) {
req.provide_ref::<String>(&self.s);
}
fn provide_mut<'a>(&'a mut self, req: &mut Demand<'a>) {
// req.provide_mut::<String>(&mut self.s);
req.with(self)
.provide_mut::<_, String>(|this| &mut this.s)
.provide_mut::<_, Bar>(|this| this);
}
}
#[test]
fn foo() {
let mut b = Bar {
s: "Bob".to_owned(),
};
let f: &mut dyn Foo = &mut b;
let s: &String = f.get_ref().unwrap();
assert_eq!(s, "Bob");
let s: &mut String = f.get_mut().unwrap();
s.push_str(" and Alice");
let _b: &mut Bar = f.get_mut().unwrap();
assert_eq!(b.s, "Bob and Alice");
}