use std::collections::BTreeMap;
use crate::client::{ApiError, Transport, info, info_request};
use crate::markets::outcomes::meta::Outcome;
use crate::utils::{Dec, Json, OutcomeSide};
use serde::{Deserialize, Deserializer};
#[must_use]
pub fn settled_outcome_request(outcome: u32) -> String {
info_request("settledOutcome", &[("outcome", Json::Number(outcome.to_string()))])
}
pub async fn settled_outcome(transport: &impl Transport, outcome: u32) -> Result<Option<SettledOutcome>, ApiError> {
info(transport, settled_outcome_request(outcome)).await
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SettledOutcome {
pub spec: Outcome,
pub settle_fraction: Dec,
#[serde(default)]
pub details: String,
#[serde(default)]
pub question: Option<SettledQuestion>,
}
impl SettledOutcome {
#[must_use]
pub fn winner(&self) -> Option<OutcomeSide> {
if self.settle_fraction == Dec::ONE {
Some(OutcomeSide::Yes)
} else if self.settle_fraction.is_zero() {
Some(OutcomeSide::No)
} else {
None
}
}
#[must_use]
pub fn pays(&self, side: OutcomeSide) -> Dec {
match side {
OutcomeSide::Yes => self.settle_fraction,
OutcomeSide::No => Dec::ONE.checked_sub(self.settle_fraction).unwrap_or(Dec::ZERO),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SettledQuestion {
pub question: u32,
pub state: String,
pub name: String,
pub description: String,
}
impl<'de> Deserialize<'de> for SettledQuestion {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
struct Raw {
question: BTreeMap<String, u32>,
#[serde(default)]
name: String,
#[serde(default)]
description: String,
}
let raw = Raw::deserialize(deserializer)?;
let Some((state, question)) = raw.question.into_iter().next() else {
return Err(serde::de::Error::custom("a settled leg's question names no id"));
};
Ok(SettledQuestion { question, state, name: raw.name, description: raw.description })
}
}
#[cfg(test)]
#[path = "tests/settled.rs"]
mod tests;