use std::fmt;
use serde::{de, Deserialize, ser, Serialize};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum TimePeriodQualifier {
ChargeablePeriods,
PeriodsHeld,
FreePeriods,
Code4,
OtherAllowancePeriods,
Hour,
Day,
NotApplicable,
InitialVisit,
SixHours,
Code11,
Code12,
Code13,
DebitDays,
CreditDays,
ExcessDays,
HazardousDays,
Holidays,
SaturdaysAndSundays,
SundaysAndHolidays,
Years,
ServiceYear,
CalendarYear,
YearToDate,
Contract,
Episode,
Visit,
Outlier,
Remaining,
Exceeded,
NotExceeded,
Lifetime,
LifetimeRemaining,
Month,
Week,
Admission,
ThreeMonths,
Used,
MemberAgeYears,
MemberAgeMonths,
Session,
Period,
Code43,
Code44,
MutuallyDefined,
}
impl TimePeriodQualifier {
pub fn code(&self) -> &str {
{
use TimePeriodQualifier::*;
match self {
ChargeablePeriods => "1",
PeriodsHeld => "2",
FreePeriods => "3",
Code4 => "4",
OtherAllowancePeriods => "5",
Hour => "6",
Day => "7",
NotApplicable => "8",
InitialVisit => "9",
SixHours => "10",
Code11 => "11",
Code12 => "12",
Code13 => "13",
DebitDays => "14",
CreditDays => "15",
ExcessDays => "16",
HazardousDays => "17",
Holidays => "18",
SaturdaysAndSundays => "19",
SundaysAndHolidays => "20",
Years => "21",
ServiceYear => "22",
CalendarYear => "23",
YearToDate => "24",
Contract => "25",
Episode => "26",
Visit => "27",
Outlier => "28",
Remaining => "29",
Exceeded => "30",
NotExceeded => "31",
Lifetime => "32",
LifetimeRemaining => "33",
Month => "34",
Week => "35",
Admission => "36",
ThreeMonths => "37",
Used => "38",
MemberAgeYears => "39",
MemberAgeMonths => "40",
Session => "41",
Period => "42",
Code43 => "43",
Code44 => "44",
MutuallyDefined => "Z",
}
}
}
pub fn from_code(code: &[u8]) -> Option<TimePeriodQualifier> {
use TimePeriodQualifier::*;
match code {
b"1" => Some(ChargeablePeriods),
b"2" => Some(PeriodsHeld),
b"3" => Some(FreePeriods),
b"4" => Some(Code4),
b"5" => Some(OtherAllowancePeriods),
b"6" => Some(Hour),
b"7" => Some(Day),
b"8" => Some(NotApplicable),
b"9" => Some(InitialVisit),
b"10" => Some(SixHours),
b"11" => Some(Code11),
b"12" => Some(Code12),
b"13" => Some(Code13),
b"14" => Some(DebitDays),
b"15" => Some(CreditDays),
b"16" => Some(ExcessDays),
b"17" => Some(HazardousDays),
b"18" => Some(Holidays),
b"19" => Some(SaturdaysAndSundays),
b"20" => Some(SundaysAndHolidays),
b"21" => Some(Years),
b"22" => Some(ServiceYear),
b"23" => Some(CalendarYear),
b"24" => Some(YearToDate),
b"25" => Some(Contract),
b"26" => Some(Episode),
b"27" => Some(Visit),
b"28" => Some(Outlier),
b"29" => Some(Remaining),
b"30" => Some(Exceeded),
b"31" => Some(NotExceeded),
b"32" => Some(Lifetime),
b"33" => Some(LifetimeRemaining),
b"34" => Some(Month),
b"35" => Some(Week),
b"36" => Some(Admission),
b"37" => Some(ThreeMonths),
b"38" => Some(Used),
b"39" => Some(MemberAgeYears),
b"40" => Some(MemberAgeMonths),
b"41" => Some(Session),
b"42" => Some(Period),
b"43" => Some(Code43),
b"44" => Some(Code44),
b"Z" => Some(MutuallyDefined),
_ => None,
}
}
fn description(&self) -> &str {
use TimePeriodQualifier::*;
match self {
ChargeablePeriods => "Chargeable Periods",
PeriodsHeld => "Periods Held",
FreePeriods => "Free Periods",
Code4 => "Saturdays, Sundays and Holidays",
OtherAllowancePeriods => "Other Allowance Periods",
Hour => "Hour",
Day => "Day",
NotApplicable => "Not Applicable",
InitialVisit => "Initial Visit",
SixHours => "Six Hours",
Code11 => "12 Hours",
Code12 => "18 Hours",
Code13 => "24 Hours",
DebitDays => "Debit Days",
CreditDays => "Credit Days",
ExcessDays => "Excess Days",
HazardousDays => "Hazardous Days",
Holidays => "Holidays",
SaturdaysAndSundays => "Saturdays and Sundays",
SundaysAndHolidays => "Sundays and Holidays",
Years => "Years",
ServiceYear => "Service Year",
CalendarYear => "Calendar Year",
YearToDate => "Year to Date",
Contract => "Contract",
Episode => "Episode",
Visit => "Visit",
Outlier => "Outlier",
Remaining => "Remaining",
Exceeded => "Exceeded",
NotExceeded => "Not Exceeded",
Lifetime => "Lifetime",
LifetimeRemaining => "Lifetime Remaining",
Month => "Month",
Week => "Week",
Admission => "Admission",
ThreeMonths => "Three Months",
Used => "Used",
MemberAgeYears => "Member Age - Years",
MemberAgeMonths => "Member Age - Months",
Session => "Session",
Period => "Period",
Code43 => "Dose(s)",
Code44 => "Month(s)",
MutuallyDefined => "Mutually Defined",
}
}
fn from_description(description: &str) -> Option<TimePeriodQualifier> {
{
use TimePeriodQualifier::*;
match description {
"Chargeable Periods" => Some(ChargeablePeriods),
"Periods Held" => Some(PeriodsHeld),
"Free Periods" => Some(FreePeriods),
"Saturdays, Sundays and Holidays" => Some(Code4),
"Other Allowance Periods" => Some(OtherAllowancePeriods),
"Hour" => Some(Hour),
"Day" => Some(Day),
"Not Applicable" => Some(NotApplicable),
"Initial Visit" => Some(InitialVisit),
"Six Hours" => Some(SixHours),
"12 Hours" => Some(Code11),
"18 Hours" => Some(Code12),
"24 Hours" => Some(Code13),
"Debit Days" => Some(DebitDays),
"Credit Days" => Some(CreditDays),
"Excess Days" => Some(ExcessDays),
"Hazardous Days" => Some(HazardousDays),
"Holidays" => Some(Holidays),
"Saturdays and Sundays" => Some(SaturdaysAndSundays),
"Sundays and Holidays" => Some(SundaysAndHolidays),
"Years" => Some(Years),
"Service Year" => Some(ServiceYear),
"Calendar Year" => Some(CalendarYear),
"Year to Date" => Some(YearToDate),
"Contract" => Some(Contract),
"Episode" => Some(Episode),
"Visit" => Some(Visit),
"Outlier" => Some(Outlier),
"Remaining" => Some(Remaining),
"Exceeded" => Some(Exceeded),
"Not Exceeded" => Some(NotExceeded),
"Lifetime" => Some(Lifetime),
"Lifetime Remaining" => Some(LifetimeRemaining),
"Month" => Some(Month),
"Week" => Some(Week),
"Admission" => Some(Admission),
"Three Months" => Some(ThreeMonths),
"Used" => Some(Used),
"Member Age - Years" => Some(MemberAgeYears),
"Member Age - Months" => Some(MemberAgeMonths),
"Session" => Some(Session),
"Period" => Some(Period),
"Dose(s)" => Some(Code43),
"Month(s)" => Some(Code44),
"Mutually Defined" => Some(MutuallyDefined),
_ => None,
}
}
}
}
impl Serialize for TimePeriodQualifier {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
let value = if serializer.is_human_readable() {
self.description()
} else {
self.code()
};
serializer.serialize_str(value)
}
}
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = TimePeriodQualifier;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Time Period Qualifier")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
TimePeriodQualifier::from_description(v)
.ok_or_else(|| E::custom(format!("Invalid Time Period Qualifier: {}", v)))
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
TimePeriodQualifier::from_code(v)
.ok_or_else(|| E::custom(
format!(
"Invalid Time Period Qualifier: {}", std::str::from_utf8(v).unwrap()
),
))
}
}
impl<'de> Deserialize<'de> for TimePeriodQualifier {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
if deserializer.is_human_readable() {
deserializer.deserialize_str(Visitor)
} else {
deserializer.deserialize_bytes(Visitor)
}
}
}