#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ChoiceWrapper<T> {
#[serde(rename = "$value")]
pub inner: T,
}
impl<T> ChoiceWrapper<T> {
pub fn new(inner: T) -> Self {
Self { inner }
}
}
impl<T> From<T> for ChoiceWrapper<T> {
fn from(inner: T) -> Self {
Self { inner }
}
}
impl<T> std::ops::Deref for ChoiceWrapper<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> std::ops::DerefMut for ChoiceWrapper<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug, Clone, PartialEq)]
enum TestChoice {
TypeA(String),
TypeB(u32),
}
#[test]
fn deref_reaches_inner() {
let w = ChoiceWrapper::new(TestChoice::TypeA("x".to_owned()));
match &*w {
TestChoice::TypeA(s) => assert_eq!(s, "x"),
TestChoice::TypeB(_) => panic!("wrong variant"),
}
}
#[test]
fn from_impl() {
let w: ChoiceWrapper<TestChoice> = TestChoice::TypeB(7).into();
assert_eq!(w.inner, TestChoice::TypeB(7));
}
#[test]
fn deref_mut_updates_inner() {
let mut w = ChoiceWrapper::new(TestChoice::TypeA("before".to_owned()));
*w = TestChoice::TypeA("after".to_owned());
match &w.inner {
TestChoice::TypeA(s) => assert_eq!(s, "after"),
TestChoice::TypeB(_) => panic!("wrong variant"),
}
}
}