use wolfram_expr::{Expr, ExprKind};
use wolfram_serialize::{from_wxf, to_wxf, FromWXF, ToWXF};
fn roundtrip<T: ToWXF + for<'de> FromWXF<'de> + PartialEq + std::fmt::Debug>(v: T) {
let bytes = to_wxf(&v, None).unwrap();
let back: T = from_wxf(&bytes).unwrap();
assert_eq!(back, v);
}
#[test]
fn option_roundtrips() {
roundtrip::<Option<i64>>(None);
roundtrip::<Option<i64>>(Some(42));
roundtrip::<Option<String>>(Some("hi".into()));
roundtrip::<Option<Option<i64>>>(Some(Some(1)));
roundtrip::<Option<Option<i64>>>(Some(None));
roundtrip::<Option<Option<i64>>>(None);
}
#[test]
fn result_roundtrips() {
roundtrip::<Result<i64, String>>(Ok(7));
roundtrip::<Result<i64, String>>(Err("boom".into()));
roundtrip::<Result<Option<i64>, i32>>(Ok(Some(3)));
}
#[test]
fn none_is_enum_list() {
let bytes = to_wxf(&Option::<i64>::None, None).unwrap();
let e: Expr = from_wxf(&bytes).unwrap();
let ExprKind::Normal(list) = e.kind() else {
panic!("None ⇒ List function, got {:?}", e);
};
let ExprKind::Symbol(head) = list.head().kind() else {
panic!("expected Symbol head, got {:?}", list.head());
};
assert_eq!(head.as_str(), "System`List");
assert_eq!(list.elements().len(), 1);
let ExprKind::String(s) = list.elements()[0].kind() else {
panic!("expected String, got {:?}", list.elements()[0]);
};
assert_eq!(s.as_str(), "None");
}
#[derive(Debug, PartialEq, ToWXF, FromWXF)]
enum MaybeInt {
Nothing,
Just(i64),
}
#[test]
fn user_enum_matches_option_wire_format() {
let just = to_wxf(&MaybeInt::Just(5), None).unwrap();
let some: Vec<u8> = to_wxf(&Some(5i64), None).unwrap();
let je: Expr = from_wxf(&just).unwrap();
let se: Expr = from_wxf(&some).unwrap();
assert!(matches!(je.kind(), ExprKind::Normal(_)));
assert!(matches!(se.kind(), ExprKind::Normal(_)));
}