1use std::mem::take;
2
3use crate::{DBData, declare_trait_object, dynamic::erase::Erase};
4
5use super::{Data, DataTrait};
6
7pub trait Opt<T: DataTrait + ?Sized>: Data {
12 fn get(&self) -> Option<&T>;
14
15 fn get_mut(&mut self) -> Option<&mut T>;
17
18 fn set_none(&mut self);
20
21 #[allow(clippy::wrong_self_convention)]
23 fn from_ref(&mut self, v: &T);
24
25 #[allow(clippy::wrong_self_convention)]
28 fn from_val(&mut self, v: &mut T);
29
30 fn set_some_with(&mut self, f: &mut dyn FnMut(&mut T));
32}
33
34impl<T, Trait> Opt<Trait> for Option<T>
35where
36 Trait: DataTrait + ?Sized,
37 T: DBData + Erase<Trait>,
38{
39 fn get(&self) -> Option<&Trait> {
40 self.as_ref().map(Erase::erase)
41 }
42
43 fn get_mut(&mut self) -> Option<&mut Trait> {
44 self.as_mut().map(Erase::erase_mut)
45 }
46
47 fn set_none(&mut self) {
48 *self = None;
49 }
50
51 fn from_ref(&mut self, v: &Trait) {
52 *self = Some(unsafe { v.downcast::<T>().clone() })
53 }
54
55 fn from_val(&mut self, v: &mut Trait) {
56 *self = Some(unsafe { take(v.downcast_mut::<T>()) })
57 }
58
59 fn set_some_with(&mut self, f: &mut dyn FnMut(&mut Trait)) {
60 let mut v: T = Default::default();
61 f(v.erase_mut());
62 *self = Some(v);
63 }
64}
65
66declare_trait_object!(DynOpt<T> = dyn Opt<T>
67where
68 T: DataTrait + ?Sized
69);