#![cfg(feature = "std")]
use optionable::OptionedConvert;
use optionable::{Optionable, OptionableConvert};
#[test]
fn derive_named_struct() {
#[derive(Optionable)]
#[optionable(derive(Clone))]
struct DeriveExample {
name: String,
pub surname: String,
}
let _ = DeriveExampleOpt {
name: None,
surname: None,
};
let partial = DeriveExampleOpt {
name: None,
surname: Some("c".to_owned()),
};
let full_partial = DeriveExampleOpt {
name: Some("a".to_owned()),
surname: Some("b".to_owned()),
};
let mut full: DeriveExample = full_partial.clone().try_into_optionable().unwrap();
assert_eq!(full.name, full_partial.name.clone().unwrap());
assert_eq!(full.surname, full_partial.surname.unwrap());
full.merge(partial.clone()).unwrap();
assert_eq!(full.name, full_partial.name.unwrap());
assert_eq!(full.surname, partial.surname.unwrap());
}
#[test]
fn derive_named_struct_required() {
#[derive(Optionable)]
#[optionable(derive(Clone))]
#[allow(dead_code)]
struct DeriveExample {
name: String,
#[optionable(required)]
surname: String,
}
let partial = DeriveExampleOpt {
name: None,
surname: "c".to_owned(),
};
let full_partial = DeriveExampleOpt {
name: Some("a".to_owned()),
surname: "b".to_owned(),
};
let mut full: DeriveExample = full_partial.clone().try_into_optionable().unwrap();
assert_eq!(full_partial.clone().name.unwrap(), full.name);
assert_eq!(full_partial.surname, full.surname);
full.merge(partial.clone()).unwrap();
assert_eq!(full_partial.name.unwrap(), full.name);
assert_eq!(partial.surname, full.surname);
}
#[test]
fn derive_unnamed_struct() {
#[allow(dead_code)]
#[derive(Optionable)]
#[optionable(derive(Clone))]
struct DeriveExample(String, pub i32);
let partial = DeriveExampleOpt(None, Some(1));
let full_partial = DeriveExampleOpt(Some("a".to_owned()), Some(42));
let mut full: DeriveExample = full_partial.clone().try_into_optionable().unwrap();
assert_eq!(full_partial.clone().0.unwrap(), full.0);
assert_eq!(full_partial.1.unwrap(), full.1);
full.merge(partial.clone()).unwrap();
assert_eq!(full_partial.0.unwrap(), full.0);
assert_eq!(partial.1.unwrap(), full.1);
}
#[test]
fn derive_unnamed_struct_required() {
#[derive(Optionable)]
#[allow(dead_code)]
#[optionable(derive(Clone))]
struct DeriveExample(String, #[optionable(required)] i32);
let partial = DeriveExampleOpt(None, 1);
let full_partial = DeriveExampleOpt(Some("a".to_owned()), 42);
let mut full: DeriveExample = full_partial.clone().try_into_optionable().unwrap();
assert_eq!(full_partial.clone().0.unwrap(), full.0);
assert_eq!(full_partial.1, full.1);
full.merge(partial.clone()).unwrap();
assert_eq!(full_partial.0.unwrap(), full.0);
assert_eq!(partial.1, full.1);
}
#[test]
fn derive_generic() {
#[allow(dead_code)]
#[derive(Optionable)]
#[optionable(no_convert)]
struct DeriveExample<T, T2, T3> {
name: T,
middle_name: T2,
#[optionable(required)]
surname: T3,
}
struct NotOptionable {}
let _ = DeriveExampleOpt::<i32, f32, NotOptionable> {
name: Some(42),
middle_name: None,
surname: NotOptionable {},
};
let _ = DeriveExampleOpt::<i32, f32, NotOptionable> {
name: Some(2),
middle_name: Some(0.25),
surname: NotOptionable {},
};
}
#[test]
fn derive_generic_convert() {
#[allow(dead_code)]
#[derive(Optionable)]
#[optionable(derive(Clone))]
struct DeriveExample<T, T2> {
name: T,
surname: T2,
}
let partial = DeriveExampleOpt::<i32, f32> {
name: Some(42),
surname: None,
};
let full_partial = DeriveExampleOpt::<i32, f32> {
name: Some(2),
surname: Some(0.25),
};
let mut full: DeriveExample<_, _> = full_partial.clone().try_into_optionable().unwrap();
assert_eq!(full_partial.clone().name.unwrap(), full.name);
assert_eq!(full_partial.surname.clone().unwrap(), full.surname);
full.merge(partial.clone()).unwrap();
assert_eq!(partial.name.unwrap(), full.name);
assert_eq!(full_partial.surname.unwrap(), full.surname);
}
type _String = <String as ::optionable::Optionable>::Optioned;
#[test]
fn derive_enum() {
#[allow(dead_code)]
#[derive(Optionable)]
#[optionable(derive(Default))]
enum DeriveExample {
#[optionable_attr(default)]
Unit,
Plain(String),
Address {
street: String,
number: u32,
},
AddressTuple(String, u32),
}
let _ = DeriveExampleOpt::Unit;
let _ = DeriveExampleOpt::Plain(None);
let _ = DeriveExampleOpt::Address {
street: None,
number: None,
};
let _ = DeriveExampleOpt::AddressTuple(None, None);
let plain_optioned = DeriveExampleOpt::Plain(Some("a".to_owned()));
let plain: DeriveExample = plain_optioned.try_into_optionable().unwrap();
if let DeriveExample::Plain(val) = plain {
assert_eq!(val, "a".to_owned());
} else {
panic!("optioned variant does not coincide with expected");
}
let address_optioned = DeriveExampleOpt::Address {
street: Some("a".to_owned()),
number: Some(42),
};
let mut address: DeriveExample = address_optioned.try_into_optionable().unwrap();
if let DeriveExample::Address { street, number } = &address {
assert_eq!(*street, "a".to_owned());
assert_eq!(*number, 42);
} else {
panic!("optioned variant does not coincide with expected");
}
let address_patch = DeriveExampleOpt::Address {
street: Some("b".to_owned()),
number: None,
};
address.merge(address_patch).unwrap();
if let DeriveExample::Address { street, number } = &address {
assert_eq!(*street, "b".to_owned());
assert_eq!(*number, 42);
} else {
panic!("optioned variant does not coincide with expected");
}
let address2_optioned = DeriveExampleOpt::AddressTuple(Some("a".to_owned()), Some(42));
let address2: DeriveExample = address2_optioned.try_into_optionable().unwrap();
if let DeriveExample::AddressTuple(street, number) = address2 {
assert_eq!(street, "a".to_owned());
assert_eq!(number, 42);
} else {
panic!("optioned variant does not coincide with expected");
}
}
#[test]
fn derive_enum_plain() {
#[allow(dead_code)]
#[derive(Optionable)]
enum DeriveExample {
Unit,
Unit2,
Unit3,
}
let _: DeriveExample = <DeriveExample as Optionable>::Optioned::Unit;
}
#[test]
fn derive_generic_advanced_types_no_convert() {
#[allow(dead_code)]
#[derive(Optionable)]
#[optionable(no_convert, derive(Clone))]
struct DeriveExample<'a, T> {
slice: &'a [T],
}
}
#[test]
fn derive_option_field() {
#[allow(dead_code)]
#[derive(Optionable)]
#[optionable(no_convert)]
struct DeriveExample<'a> {
_el: Option<&'a str>,
}
let _ = DeriveExampleOpt { _el: Some("a") };
}
#[test]
fn derive_option_wrap_field() {
#[allow(dead_code)]
#[derive(Optionable)]
#[optionable(option_wrap, no_convert)]
struct DeriveExample<'a> {
el: Option<&'a str>,
}
let _ = DeriveExampleOpt {
el: Some(Some("a")),
};
}