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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
pub( crate ) mod private
{
  use std::{ sync::Arc, cell::RefCell };
  use anymap::{ Map, any::CloneAny };

  /// Container for contexts values
  ///
  /// # Examples:
  ///
  /// ```
  /// use wca::Context;
  ///
  /// let ctx = Context::default();
  ///
  /// ctx.insert( 42 );
  /// assert_eq!( 42, *ctx.get_ref().unwrap() );
  /// ```
  ///
  /// ```
  /// # use wca::{ Routine, Context, Value, Args, Props };
  /// let routine = Routine::new_with_ctx
  /// (
  ///   | ( args, props ), ctx |
  ///   {
  ///     let first_arg : i32 = args.get_owned( 0 ).unwrap_or_default();
  ///     let ctx_value : &mut i32 = ctx.get_or_default();
  ///
  ///     *ctx_value += first_arg;
  ///
  ///     Ok( () )
  ///   }
  /// );
  /// let ctx = Context::default();
  /// if let Routine::WithContext( callback ) = routine
  /// {
  ///   callback( ( Args( vec![ Value::Number( 1.0 ) ] ), Props( Default::default() ) ), ctx.clone() ).unwrap();
  /// }
  /// assert_eq!( 1, *ctx.get_ref().unwrap() );
  /// ```
  // CloneAny needs to deep clone of Context
  // qqq : ?
  #[ derive( Debug, Clone, former::Former ) ]
  pub struct Context
  {
    inner : Arc< RefCell< Map::< dyn CloneAny > > >
  }

  impl ContextFormer
  {
    /// Initialize Context with some value
    pub fn with< T : CloneAny >( mut self, value : T ) -> Self
    {
      if self.container.inner.is_none()
      {
        self.container.inner = Some( Arc::new( RefCell::new( Map::< dyn CloneAny >::new() ) ) );
      }
      self.container.inner.as_ref().map( | inner | inner.borrow_mut().insert( value ) );
      self
    }
  }

  impl Default for Context
  {
    fn default() -> Self
    {
      Self { inner : Arc::new( RefCell::new( Map::< dyn CloneAny >::new() ) ) }
    }
  }

  impl Context
  {
     /// Insert the T value to the context. If it is already exists - replace it
     pub fn insert< T : CloneAny >( &self, value : T )
     {
       self.inner.borrow_mut().insert( value );
     }

     /// Removes the T value from the context
     pub fn remove< T : CloneAny >( &mut self ) -> Option< T >
     {
       self.inner.borrow_mut().remove::< T >()
     }

    // qqq : Bohdan : why unsafe?
    /// Return immutable reference on interior object. ! Unsafe !
    pub fn get_ref< T : CloneAny >( &self ) -> Option< &T >
    {
      unsafe{ self.inner.as_ptr().as_ref()?.get() }
    }

    /// Return mutable reference on interior object. ! Unsafe !
    pub fn get_mut< T : CloneAny >( &self ) -> Option< &mut T >
    {
      unsafe { self.inner.as_ptr().as_mut()?.get_mut() }
    }

    /// Insert the value if it doesn't exists, or take an existing value and return mutable reference to it
    pub fn get_or_insert< T : CloneAny >( &self, value : T ) -> &mut T
    {
      if let Some( value ) = self.get_mut()
      {
        value
      }
      else
      {
        self.insert( value );
        self.get_mut().unwrap()
      }
    }

    /// Insert default value if it doesn't exists, or take an existing value and return mutable reference to it
    pub fn get_or_default< T : CloneAny + Default >( &self ) -> &mut T
    {
      self.get_or_insert( T::default() )
    }

    /// Make a deep clone of the context
    // qqq : for Bohdan : why is it deep? how is it deep?
    // qqq : how is it useful? Is it? Examples?
    pub( crate ) fn deep_clone( &self ) -> Self
    {
      Self { inner : Arc::new( RefCell::new( ( *self.inner ).borrow_mut().clone() ) ) }
    }
  }
}

//

crate::mod_interface!
{
  exposed use Context;
}