use std::fmt::Debug;
use crate::{inline_string,
throws,
tiny_inline_string,
CommonError,
CommonResult,
FlexBox,
FlexBoxId,
InlineVec};
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct HasFocus {
id_vec: InlineVec<FlexBoxId>,
}
impl Default for HasFocus {
fn default() -> Self {
Self {
id_vec: InlineVec::with_capacity(2),
}
}
}
impl HasFocus {
pub fn is_empty(&self) -> bool { self.id_vec.is_empty() }
pub fn is_set(&self) -> bool { !self.is_empty() }
pub fn get_id(&self) -> Option<FlexBoxId> { self.id_vec.last().copied() }
pub fn set_id(&mut self, id: FlexBoxId) {
if self.id_vec.is_empty() {
self.id_vec.push(id);
} else {
let it = self.id_vec.last_mut().unwrap();
*it = id;
}
}
pub fn does_id_have_focus(&self, id: FlexBoxId) -> bool {
if self.id_vec.is_empty() {
false
} else {
let it = self.id_vec.last().unwrap();
*it == id
}
}
pub fn does_current_box_have_focus(&self, current_box: FlexBox) -> bool {
self.does_id_have_focus(current_box.id)
}
}
impl HasFocus {
pub fn try_set_modal_id(&mut self, id: FlexBoxId) -> CommonResult<()> {
throws!({
if !self.is_set() {
let msg = "Modal id can only be set if id is already set. id is not set.";
return CommonError::new_error_result_with_only_msg(msg);
}
if self.is_modal_set() {
let msg = inline_string!(
"Modal id is already set to {a}. Can't set it to {b}.",
a = match self.get_id() {
Some(existing_id) => tiny_inline_string!("{existing_id:?}"),
None => tiny_inline_string!("None"),
},
b = tiny_inline_string!("{id:?}")
);
return CommonError::new_error_result_with_only_msg(&msg);
}
self.id_vec.push(id);
});
}
pub fn is_modal_set(&self) -> bool { self.id_vec.len() == 2 }
pub fn is_modal_id(&self, id: FlexBoxId) -> bool {
self.is_modal_set() && self.does_id_have_focus(id)
}
pub fn reset_modal_id(&mut self) {
if self.is_modal_set() {
self.id_vec.pop();
}
}
}
#[cfg(test)]
mod has_focus_tests {
use super::*;
use crate::assert_eq2;
#[test]
fn works_with_normal_id() {
let mut has_focus = HasFocus::default();
assert!(has_focus.is_empty());
assert!(!has_focus.is_set());
has_focus.set_id(FlexBoxId::from(1));
assert!(!has_focus.is_empty());
assert!(has_focus.is_set());
assert_eq2!(has_focus.get_id(), Some(FlexBoxId::from(1)));
assert!(has_focus.does_id_have_focus(FlexBoxId::from(1)));
let current_box_1 = FlexBox {
id: FlexBoxId::from(1),
..Default::default()
};
assert!(has_focus.does_current_box_have_focus(current_box_1));
has_focus.set_id(FlexBoxId::from(2));
assert!(!has_focus.is_empty());
assert!(has_focus.is_set());
assert_eq2!(has_focus.get_id(), Some(FlexBoxId::from(2)));
assert!(has_focus.does_id_have_focus(FlexBoxId::from(2)));
let current_box_2 = FlexBox {
id: FlexBoxId::from(2),
..Default::default()
};
assert!(has_focus.does_current_box_have_focus(current_box_2));
assert!(!has_focus.does_id_have_focus(FlexBoxId::from(1)));
assert!(!has_focus.does_current_box_have_focus(current_box_1));
}
#[test]
fn fails_with_modal_id_with_no_id_set() {
let mut has_focus = HasFocus::default();
assert!(has_focus.is_empty());
assert!(!has_focus.is_set());
let my_err_box = has_focus
.try_set_modal_id(FlexBoxId::from(1))
.err()
.unwrap();
assert_eq2!(my_err_box.is::<CommonError>(), true);
let my_err = my_err_box.downcast_ref::<CommonError>().unwrap();
let CommonError {
error_message: msg, ..
} = my_err;
assert_eq2!(
msg.as_ref().unwrap(),
"Modal id can only be set if id is already set. id is not set."
);
assert!(!has_focus.is_modal_set());
assert!(!has_focus.is_modal_id(FlexBoxId::from(1)));
has_focus.reset_modal_id();
}
#[test]
fn works_with_modal_id_when_id_is_set() {
let mut has_focus = HasFocus::default();
assert!(has_focus.is_empty());
assert!(!has_focus.is_set());
has_focus.set_id(FlexBoxId::from(1));
assert!(has_focus.try_set_modal_id(FlexBoxId::from(2)).is_ok());
assert!(has_focus.is_modal_set());
assert!(has_focus.is_modal_id(FlexBoxId::from(2)));
assert!(!has_focus.is_modal_id(FlexBoxId::from(1)));
assert_eq2!(has_focus.get_id(), Some(FlexBoxId::from(2)));
assert!(has_focus.try_set_modal_id(FlexBoxId::from(3)).is_err());
assert!(has_focus.is_modal_set());
assert!(has_focus.is_modal_id(FlexBoxId::from(2)));
has_focus.reset_modal_id();
assert!(!has_focus.is_modal_set());
assert!(!has_focus.is_modal_id(FlexBoxId::from(1)));
assert_eq2!(has_focus.get_id(), Some(FlexBoxId::from(1)));
assert_eq2!(has_focus.does_id_have_focus(FlexBoxId::from(1)), true);
let current_box_1 = FlexBox {
id: FlexBoxId::from(1),
..Default::default()
};
assert!(has_focus.does_current_box_have_focus(current_box_1));
assert!(has_focus.is_set());
assert!(!has_focus.is_empty());
}
}