#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum RateMove {
Increase,
Decrease,
NoChange,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Family {
BinaryPrice,
PriceTouch,
ScalarPrice,
ContestWinner,
ContestParticipant,
ContestDraw,
TournamentParticipant,
SportsScalar,
SportsOverUnder,
PolicyRate(RateMove),
Recurring,
Fallback,
Named,
ContestResult,
TournamentWinner,
PolicyRateDecision,
Template,
}
impl Family {
#[must_use]
pub const fn is_question(self) -> bool {
matches!(self, Family::ContestResult | Family::TournamentWinner | Family::PolicyRateDecision)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Template {
pub family: Family,
pub version: Option<u8>,
}
impl Template {
#[must_use]
pub fn classify(name: &str) -> Template {
let name = name.trim();
let fallback = ["template fallback", "fallback", "recurring fallback"];
if fallback.iter().any(|spelling| name.eq_ignore_ascii_case(spelling)) {
return Template { family: Family::Fallback, version: None };
}
let Some(rest) = name.strip_prefix("template:") else {
let family = if name.starts_with("Recurring") { Family::Recurring } else { Family::Named };
return Template { family, version: None };
};
let stem = rest.trim_end_matches(|c: char| c.is_ascii_digit());
let digits = &rest[stem.len()..];
let family = match stem {
"binaryPrice" => Family::BinaryPrice,
"priceTouch" => Family::PriceTouch,
"scalePrice" | "scalarPrice" => Family::ScalarPrice,
"sportsContestWinner" => Family::ContestWinner,
"sportsContestParticipant" => Family::ContestParticipant,
"sportsContestDraw" => Family::ContestDraw,
"sportsTournamentParticipant" => Family::TournamentParticipant,
"sportsScalarMarket" => Family::SportsScalar,
"sportsOverUnderMarket" => Family::SportsOverUnder,
"policyRateIncrease" => Family::PolicyRate(RateMove::Increase),
"policyRateDecrease" => Family::PolicyRate(RateMove::Decrease),
"policyRateNoChange" => Family::PolicyRate(RateMove::NoChange),
"sportsContestResult" => Family::ContestResult,
"sportsTournamentWinner" => Family::TournamentWinner,
"policyRateDecision" => Family::PolicyRateDecision,
_ => Family::Template,
};
Template { family, version: digits.parse().ok() }
}
}
#[cfg(test)]
#[path = "tests/family.rs"]
mod tests;