ctx/
with_value.rs

1use std::any::Any;
2use std::time::Instant;
3use {Context, InnerContext, ContextError};
4use futures::{Future, Poll, Async};
5
6pub struct WithValue<V>
7    where V: Any
8{
9    parent: Context,
10    val: V,
11}
12
13impl<V> InnerContext for WithValue<V>
14    where V: Any
15{
16    fn deadline(&self) -> Option<Instant> {
17        None
18    }
19
20    fn value(&self) -> Option<&Any> {
21        let val_any = &self.val as &Any;
22        Some(val_any)
23    }
24
25    fn parent(&self) -> Option<Context> {
26        Some(self.parent.clone())
27    }
28}
29
30impl<V> Future for WithValue<V>
31    where V: Any
32{
33    type Item = ();
34    type Error = ContextError;
35
36    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
37        Ok(Async::NotReady)
38    }
39}
40
41/// Returns a copy of parent, but with the given value associated to it.
42///
43/// Context values should only be used for request-scoped data that transists
44/// processes and API boundaries and not for passing optional parameters to
45/// functions.
46///
47/// It is recommended to use structs as values instead of simple data types
48/// like strings and ints to be very specific of what result to expect when
49/// retrieving a value. Having values of the same data type among the ancestors
50/// would always return the first hit.
51///
52/// # Examples
53///
54/// ```
55/// use ctx::{Context, with_value, background};
56///
57/// let a = with_value(background(), 42);
58/// let b = with_value(a, 1.0);
59/// assert_eq!(b.value(), Some(42));
60/// assert_eq!(b.value(), Some(1.0));
61/// ```
62pub fn with_value<V>(parent: Context, val: V) -> Context
63    where V: Any
64{
65    Context::new(WithValue {
66                     parent: parent,
67                     val: val,
68                 })
69}
70
71#[cfg(test)]
72mod test {
73    use with_value::with_value;
74    use background;
75
76    #[test]
77    fn same_type_2test() {
78        let a = with_value(background(), 42);
79        let b = with_value(a, 1.0);
80        assert_eq!(b.value(), Some(42));
81        assert_eq!(b.value(), Some(1.0));
82    }
83
84    #[test]
85    fn same_type_test() {
86        let a = with_value(background(), 1);
87        let b = with_value(a, 2);
88        assert_eq!(b.value(), Some(2));
89    }
90
91    #[test]
92    fn same_type_workaround_test() {
93        #[derive(Debug, PartialEq, Clone)]
94        struct A(i32);
95        #[derive(Debug, PartialEq, Clone)]
96        struct B(i32);
97        let a = with_value(background(), A(1));
98        let b = with_value(a, B(1));
99        assert_eq!(b.value(), Some(A(1)));
100    }
101
102    #[test]
103    fn clone_test() {
104        let ctx = with_value(background(), 42);
105        let clone = ctx.clone();
106
107        assert_eq!(ctx.value(), Some(42));
108        assert_eq!(clone.value(), Some(42));
109    }
110}