use std::marker::PhantomData;
use crate::InjectionContext;
pub struct FunctionHandle<'a, O> {
ctx: &'a InjectionContext,
func_ptr: usize,
_marker: PhantomData<O>,
}
impl<'a, O: Clone + Send + Sync + 'static> FunctionHandle<'a, O> {
pub(crate) fn new(ctx: &'a InjectionContext, func_ptr: usize) -> Self {
Self {
ctx,
func_ptr,
_marker: PhantomData,
}
}
pub fn override_with(&self, value: O) -> &Self {
self.ctx.overrides().set(self.func_ptr, value);
self
}
pub fn clear_override(&self) -> &Self {
self.ctx.overrides().remove(self.func_ptr);
self
}
pub fn has_override(&self) -> bool {
self.ctx.overrides().has(self.func_ptr)
}
pub fn get_override(&self) -> Option<O> {
self.ctx.overrides().get(self.func_ptr)
}
pub fn func_ptr(&self) -> usize {
self.func_ptr
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use crate::{InjectionContext, SingletonScope};
fn create_string() -> String {
"production".to_string()
}
fn create_other_string() -> String {
"other_production".to_string()
}
#[test]
fn test_override_with() {
let singleton = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton).build();
ctx.dependency(create_string)
.override_with("mock".to_string());
assert!(ctx.dependency(create_string).has_override());
assert_eq!(
ctx.dependency(create_string).get_override(),
Some("mock".to_string())
);
}
#[test]
fn test_clear_override() {
let singleton = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton).build();
ctx.dependency(create_string)
.override_with("mock".to_string());
assert!(ctx.dependency(create_string).has_override());
ctx.dependency(create_string).clear_override();
assert!(!ctx.dependency(create_string).has_override());
}
#[test]
fn test_different_functions_independent() {
let singleton = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton).build();
ctx.dependency(create_string)
.override_with("mock_1".to_string());
ctx.dependency(create_other_string)
.override_with("mock_2".to_string());
assert_eq!(
ctx.dependency(create_string).get_override(),
Some("mock_1".to_string())
);
assert_eq!(
ctx.dependency(create_other_string).get_override(),
Some("mock_2".to_string())
);
}
#[test]
fn test_func_ptr() {
let singleton = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton).build();
let handle = ctx.dependency(create_string);
assert_eq!(handle.func_ptr(), create_string as *const () as usize);
}
}