#![cfg(feature = "serde")]
use dds_bridge::{
Bid, Card, Contract, FullDeal, Hand, Holding, Level, Penalty, Rank, Seat, SeatFlags, Strain,
Suit,
};
fn roundtrip<T>(value: &T) -> serde_json::Result<()>
where
T: serde::Serialize + serde::de::DeserializeOwned + core::fmt::Debug + PartialEq,
{
let json = serde_json::to_string(value)?;
let parsed: T = serde_json::from_str(&json)?;
assert_eq!(&parsed, value, "round-trip mismatch for {json}");
Ok(())
}
#[test]
fn strain_json_is_variant_name() -> serde_json::Result<()> {
assert_eq!(serde_json::to_string(&Strain::Spades)?, "\"Spades\"");
assert_eq!(serde_json::to_string(&Strain::Notrump)?, "\"Notrump\"");
for &s in &Strain::ASC {
roundtrip(&s)?;
}
Ok(())
}
#[test]
fn suit_json_roundtrip() -> serde_json::Result<()> {
for &s in &Suit::ASC {
roundtrip(&s)?;
}
Ok(())
}
#[test]
fn seat_json_roundtrip() -> serde_json::Result<()> {
for &s in &Seat::ALL {
roundtrip(&s)?;
}
Ok(())
}
#[test]
fn rank_json_is_number() -> serde_json::Result<()> {
assert_eq!(serde_json::to_string(&Rank::A)?, "14");
for n in 2..=14 {
roundtrip(&Rank::new(n))?;
}
Ok(())
}
#[test]
fn level_json_is_number() -> serde_json::Result<()> {
assert_eq!(serde_json::to_string(&Level::new(4))?, "4");
for n in 1..=7 {
roundtrip(&Level::new(n))?;
}
Ok(())
}
#[test]
fn penalty_json_roundtrip() -> serde_json::Result<()> {
for p in [Penalty::Undoubled, Penalty::Doubled, Penalty::Redoubled] {
roundtrip(&p)?;
}
Ok(())
}
#[test]
fn card_json_is_string() -> serde_json::Result<()> {
let c = Card {
suit: Suit::Spades,
rank: Rank::A,
};
assert_eq!(serde_json::to_string(&c)?, "\"♠A\"");
roundtrip(&c)
}
#[test]
fn bid_json_is_string() -> serde_json::Result<()> {
let b = Bid::new(3, Strain::Notrump);
assert_eq!(serde_json::to_string(&b)?, "\"3NT\"");
roundtrip(&b)
}
#[test]
fn contract_json_is_string() -> serde_json::Result<()> {
let c = Contract::new(4, Strain::Hearts, Penalty::Doubled);
assert_eq!(serde_json::to_string(&c)?, "\"4♥x\"");
roundtrip(&c)
}
#[test]
fn holding_json_is_string() -> anyhow::Result<()> {
let h: Holding = "AKQJT".parse()?;
assert_eq!(serde_json::to_string(&h)?, "\"AKQJT\"");
roundtrip(&h)?;
Ok(())
}
#[test]
fn hand_json_is_string() -> anyhow::Result<()> {
let h: Hand = "AKQJ.T98.765.432".parse()?;
assert_eq!(serde_json::to_string(&h)?, "\"AKQJ.T98.765.432\"");
roundtrip(&h)?;
Ok(())
}
#[test]
fn full_deal_json_is_pbn_string() -> anyhow::Result<()> {
let d: FullDeal =
"N:AKQJT98765432... .AKQJT98765432.. ..AKQJT98765432. ...AKQJT98765432".parse()?;
let json = serde_json::to_string(&d)?;
assert!(json.starts_with("\"N:"), "unexpected: {json}");
roundtrip(&d)?;
Ok(())
}
#[test]
fn seat_flags_json_roundtrip() -> serde_json::Result<()> {
roundtrip(&SeatFlags::NS)?;
roundtrip(&SeatFlags::EW)?;
roundtrip(&SeatFlags::ALL)?;
roundtrip(&(SeatFlags::NORTH | SeatFlags::SOUTH))
}