use std::sync::{Arc, Mutex};
use crate::input::{ComponentInputs, TextInputId};
#[derive(Clone)]
pub struct MockComponentInputs {
inputs: Arc<Mutex<MockComponentInputsInner>>,
}
struct MockComponentInputsInner {
text: Box<dyn FnMut(TextInputId) -> String>,
}
impl MockComponentInputs {
pub fn new() -> Self {
Self {
inputs: Arc::new(Mutex::new(MockComponentInputsInner {
text: Box::new(|_| panic!("Use `MockComponentInputs::set_text_input`")),
})),
}
}
pub fn set_text_input(&self, text_input: impl FnMut(TextInputId) -> String + 'static) {
self.inputs.lock().unwrap().text = Box::new(text_input);
}
pub fn component_inputs(&self) -> ComponentInputs {
let inputs = self.clone();
let inputs = Box::into_raw(Box::new(inputs));
ComponentInputs {
ctx: inputs.cast(),
free_ctx: |inputs| {
let inputs: *mut MockComponentInputs = inputs.cast();
let inputs: Box<MockComponentInputs> = unsafe { Box::from_raw(inputs) };
drop(inputs)
},
text: |inputs, input_id| {
let inputs: *mut MockComponentInputs = inputs.cast();
let inputs = unsafe { &*inputs };
let mut inputs = inputs.inputs.lock().unwrap();
(inputs.text)(input_id)
},
}
}
}