use std::fmt;
use serde::{de, Deserialize, ser, Serialize};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DosageFormCode {
CombinationForms,
TestKits,
ContraceptiveDevices,
Devices,
PatchOrDisc,
Code06,
Dosepak,
Tablet,
EntericCoatedTablet,
SustainedReleaseTablet,
BuccalOrSublingualTablet,
ChewableTablet,
SolubleTablet,
TabletUnspecified,
Capsule,
SustainedReleaseCapsule,
CapsuleUnspecified,
Tablet21DaySupply,
Tablet28DaySupply,
EntericCoatedCapsule,
LozengeOrTroche,
InternalPowder,
ChewingGum,
Granules,
Swabs,
Injection,
SustainedReleaseInjection,
InjectableUnspecified,
InjectableLyophilizedPowder,
Ophthalmic,
OphthalmicLiquid,
OphthalmicOrOtic,
Code53,
Elixir,
Suspension,
Syrup,
Solution,
Emulsion,
Drops,
PediatricLiquid,
Liquid,
Code68,
RectalCreamOrOintment,
RectalSuppository,
VaginalSuppository,
VaginalTablet,
VaginalCream,
VaginalFoam,
UrethralSuppository,
Enema,
Douche,
VaginalOintment,
ContraceptiveSponge,
ExternalOintment,
ExternalCream,
DentalProduct,
AerosolPowder,
AerosolSpray,
ExternalLiquid,
ExternalPowder,
DentalMouthRinse,
Code88,
Irrigant,
Gargle,
ThroatSprayAndSwabs,
Nasal,
Inhalant,
Otic,
Soap,
Stick,
DressingOrBandage,
MiscellaneousUnspecified,
}
impl DosageFormCode {
pub fn code(&self) -> &str {
{
use DosageFormCode::*;
match self {
CombinationForms => "01",
TestKits => "02",
ContraceptiveDevices => "03",
Devices => "04",
PatchOrDisc => "05",
Code06 => "06",
Dosepak => "07",
Tablet => "10",
EntericCoatedTablet => "11",
SustainedReleaseTablet => "12",
BuccalOrSublingualTablet => "13",
ChewableTablet => "14",
SolubleTablet => "15",
TabletUnspecified => "16",
Capsule => "20",
SustainedReleaseCapsule => "21",
CapsuleUnspecified => "22",
Tablet21DaySupply => "23",
Tablet28DaySupply => "24",
EntericCoatedCapsule => "25",
LozengeOrTroche => "30",
InternalPowder => "31",
ChewingGum => "32",
Granules => "33",
Swabs => "34",
Injection => "40",
SustainedReleaseInjection => "41",
InjectableUnspecified => "42",
InjectableLyophilizedPowder => "43",
Ophthalmic => "50",
OphthalmicLiquid => "51",
OphthalmicOrOtic => "52",
Code53 => "53",
Elixir => "60",
Suspension => "61",
Syrup => "62",
Solution => "63",
Emulsion => "64",
Drops => "65",
PediatricLiquid => "66",
Liquid => "67",
Code68 => "68",
RectalCreamOrOintment => "69",
RectalSuppository => "70",
VaginalSuppository => "71",
VaginalTablet => "72",
VaginalCream => "73",
VaginalFoam => "74",
UrethralSuppository => "75",
Enema => "76",
Douche => "77",
VaginalOintment => "78",
ContraceptiveSponge => "79",
ExternalOintment => "80",
ExternalCream => "81",
DentalProduct => "82",
AerosolPowder => "83",
AerosolSpray => "84",
ExternalLiquid => "85",
ExternalPowder => "86",
DentalMouthRinse => "87",
Code88 => "88",
Irrigant => "90",
Gargle => "91",
ThroatSprayAndSwabs => "92",
Nasal => "93",
Inhalant => "94",
Otic => "95",
Soap => "96",
Stick => "97",
DressingOrBandage => "98",
MiscellaneousUnspecified => "99",
}
}
}
pub fn from_code(code: &[u8]) -> Option<DosageFormCode> {
use DosageFormCode::*;
match code {
b"01" => Some(CombinationForms),
b"02" => Some(TestKits),
b"03" => Some(ContraceptiveDevices),
b"04" => Some(Devices),
b"05" => Some(PatchOrDisc),
b"06" => Some(Code06),
b"07" => Some(Dosepak),
b"10" => Some(Tablet),
b"11" => Some(EntericCoatedTablet),
b"12" => Some(SustainedReleaseTablet),
b"13" => Some(BuccalOrSublingualTablet),
b"14" => Some(ChewableTablet),
b"15" => Some(SolubleTablet),
b"16" => Some(TabletUnspecified),
b"20" => Some(Capsule),
b"21" => Some(SustainedReleaseCapsule),
b"22" => Some(CapsuleUnspecified),
b"23" => Some(Tablet21DaySupply),
b"24" => Some(Tablet28DaySupply),
b"25" => Some(EntericCoatedCapsule),
b"30" => Some(LozengeOrTroche),
b"31" => Some(InternalPowder),
b"32" => Some(ChewingGum),
b"33" => Some(Granules),
b"34" => Some(Swabs),
b"40" => Some(Injection),
b"41" => Some(SustainedReleaseInjection),
b"42" => Some(InjectableUnspecified),
b"43" => Some(InjectableLyophilizedPowder),
b"50" => Some(Ophthalmic),
b"51" => Some(OphthalmicLiquid),
b"52" => Some(OphthalmicOrOtic),
b"53" => Some(Code53),
b"60" => Some(Elixir),
b"61" => Some(Suspension),
b"62" => Some(Syrup),
b"63" => Some(Solution),
b"64" => Some(Emulsion),
b"65" => Some(Drops),
b"66" => Some(PediatricLiquid),
b"67" => Some(Liquid),
b"68" => Some(Code68),
b"69" => Some(RectalCreamOrOintment),
b"70" => Some(RectalSuppository),
b"71" => Some(VaginalSuppository),
b"72" => Some(VaginalTablet),
b"73" => Some(VaginalCream),
b"74" => Some(VaginalFoam),
b"75" => Some(UrethralSuppository),
b"76" => Some(Enema),
b"77" => Some(Douche),
b"78" => Some(VaginalOintment),
b"79" => Some(ContraceptiveSponge),
b"80" => Some(ExternalOintment),
b"81" => Some(ExternalCream),
b"82" => Some(DentalProduct),
b"83" => Some(AerosolPowder),
b"84" => Some(AerosolSpray),
b"85" => Some(ExternalLiquid),
b"86" => Some(ExternalPowder),
b"87" => Some(DentalMouthRinse),
b"88" => Some(Code88),
b"90" => Some(Irrigant),
b"91" => Some(Gargle),
b"92" => Some(ThroatSprayAndSwabs),
b"93" => Some(Nasal),
b"94" => Some(Inhalant),
b"95" => Some(Otic),
b"96" => Some(Soap),
b"97" => Some(Stick),
b"98" => Some(DressingOrBandage),
b"99" => Some(MiscellaneousUnspecified),
_ => None,
}
}
fn description(&self) -> &str {
use DosageFormCode::*;
match self {
CombinationForms => "Combination Forms",
TestKits => "Test Kits",
ContraceptiveDevices => "Contraceptive Devices",
Devices => "Devices",
PatchOrDisc => "Patch or Disc",
Code06 => "Chewable (candy) Bar",
Dosepak => "Dosepak",
Tablet => "Tablet",
EntericCoatedTablet => "Enteric Coated Tablet",
SustainedReleaseTablet => "Sustained Release Tablet",
BuccalOrSublingualTablet => "Buccal or Sublingual Tablet",
ChewableTablet => "Chewable Tablet",
SolubleTablet => "Soluble Tablet",
TabletUnspecified => "Tablet Unspecified",
Capsule => "Capsule",
SustainedReleaseCapsule => "Sustained Release Capsule",
CapsuleUnspecified => "Capsule Unspecified",
Tablet21DaySupply => "Tablet 21 Day Supply",
Tablet28DaySupply => "Tablet 28 Day Supply",
EntericCoatedCapsule => "Enteric Coated Capsule",
LozengeOrTroche => "Lozenge or Troche",
InternalPowder => "Internal Powder",
ChewingGum => "Chewing Gum",
Granules => "Granules",
Swabs => "Swabs",
Injection => "Injection",
SustainedReleaseInjection => "Sustained Release Injection",
InjectableUnspecified => "Injectable Unspecified",
InjectableLyophilizedPowder => "Injectable Lyophilized Powder",
Ophthalmic => "Ophthalmic",
OphthalmicLiquid => "Ophthalmic Liquid",
OphthalmicOrOtic => "Ophthalmic or Otic",
Code53 => "Ophthalmic Liquid (Compliance Cap)",
Elixir => "Elixir",
Suspension => "Suspension",
Syrup => "Syrup",
Solution => "Solution",
Emulsion => "Emulsion",
Drops => "Drops",
PediatricLiquid => "Pediatric Liquid",
Liquid => "Liquid",
Code68 => "Oral, Liquid and Sustained Release",
RectalCreamOrOintment => "Rectal Cream or Ointment",
RectalSuppository => "Rectal Suppository",
VaginalSuppository => "Vaginal Suppository",
VaginalTablet => "Vaginal Tablet",
VaginalCream => "Vaginal Cream",
VaginalFoam => "Vaginal Foam",
UrethralSuppository => "Urethral Suppository",
Enema => "Enema",
Douche => "Douche",
VaginalOintment => "Vaginal Ointment",
ContraceptiveSponge => "Contraceptive Sponge",
ExternalOintment => "External Ointment",
ExternalCream => "External Cream",
DentalProduct => "Dental Product",
AerosolPowder => "Aerosol Powder",
AerosolSpray => "Aerosol Spray",
ExternalLiquid => "External Liquid",
ExternalPowder => "External Powder",
DentalMouthRinse => "Dental Mouth Rinse",
Code88 => "Inhalant (Refill Canister Only)",
Irrigant => "Irrigant",
Gargle => "Gargle",
ThroatSprayAndSwabs => "Throat Spray and Swabs",
Nasal => "Nasal",
Inhalant => "Inhalant",
Otic => "Otic",
Soap => "Soap",
Stick => "Stick",
DressingOrBandage => "Dressing or Bandage",
MiscellaneousUnspecified => "Miscellaneous Unspecified",
}
}
fn from_description(description: &str) -> Option<DosageFormCode> {
{
use DosageFormCode::*;
match description {
"Combination Forms" => Some(CombinationForms),
"Test Kits" => Some(TestKits),
"Contraceptive Devices" => Some(ContraceptiveDevices),
"Devices" => Some(Devices),
"Patch or Disc" => Some(PatchOrDisc),
"Chewable (candy) Bar" => Some(Code06),
"Dosepak" => Some(Dosepak),
"Tablet" => Some(Tablet),
"Enteric Coated Tablet" => Some(EntericCoatedTablet),
"Sustained Release Tablet" => Some(SustainedReleaseTablet),
"Buccal or Sublingual Tablet" => Some(BuccalOrSublingualTablet),
"Chewable Tablet" => Some(ChewableTablet),
"Soluble Tablet" => Some(SolubleTablet),
"Tablet Unspecified" => Some(TabletUnspecified),
"Capsule" => Some(Capsule),
"Sustained Release Capsule" => Some(SustainedReleaseCapsule),
"Capsule Unspecified" => Some(CapsuleUnspecified),
"Tablet 21 Day Supply" => Some(Tablet21DaySupply),
"Tablet 28 Day Supply" => Some(Tablet28DaySupply),
"Enteric Coated Capsule" => Some(EntericCoatedCapsule),
"Lozenge or Troche" => Some(LozengeOrTroche),
"Internal Powder" => Some(InternalPowder),
"Chewing Gum" => Some(ChewingGum),
"Granules" => Some(Granules),
"Swabs" => Some(Swabs),
"Injection" => Some(Injection),
"Sustained Release Injection" => Some(SustainedReleaseInjection),
"Injectable Unspecified" => Some(InjectableUnspecified),
"Injectable Lyophilized Powder" => Some(InjectableLyophilizedPowder),
"Ophthalmic" => Some(Ophthalmic),
"Ophthalmic Liquid" => Some(OphthalmicLiquid),
"Ophthalmic or Otic" => Some(OphthalmicOrOtic),
"Ophthalmic Liquid (Compliance Cap)" => Some(Code53),
"Elixir" => Some(Elixir),
"Suspension" => Some(Suspension),
"Syrup" => Some(Syrup),
"Solution" => Some(Solution),
"Emulsion" => Some(Emulsion),
"Drops" => Some(Drops),
"Pediatric Liquid" => Some(PediatricLiquid),
"Liquid" => Some(Liquid),
"Oral, Liquid and Sustained Release" => Some(Code68),
"Rectal Cream or Ointment" => Some(RectalCreamOrOintment),
"Rectal Suppository" => Some(RectalSuppository),
"Vaginal Suppository" => Some(VaginalSuppository),
"Vaginal Tablet" => Some(VaginalTablet),
"Vaginal Cream" => Some(VaginalCream),
"Vaginal Foam" => Some(VaginalFoam),
"Urethral Suppository" => Some(UrethralSuppository),
"Enema" => Some(Enema),
"Douche" => Some(Douche),
"Vaginal Ointment" => Some(VaginalOintment),
"Contraceptive Sponge" => Some(ContraceptiveSponge),
"External Ointment" => Some(ExternalOintment),
"External Cream" => Some(ExternalCream),
"Dental Product" => Some(DentalProduct),
"Aerosol Powder" => Some(AerosolPowder),
"Aerosol Spray" => Some(AerosolSpray),
"External Liquid" => Some(ExternalLiquid),
"External Powder" => Some(ExternalPowder),
"Dental Mouth Rinse" => Some(DentalMouthRinse),
"Inhalant (Refill Canister Only)" => Some(Code88),
"Irrigant" => Some(Irrigant),
"Gargle" => Some(Gargle),
"Throat Spray and Swabs" => Some(ThroatSprayAndSwabs),
"Nasal" => Some(Nasal),
"Inhalant" => Some(Inhalant),
"Otic" => Some(Otic),
"Soap" => Some(Soap),
"Stick" => Some(Stick),
"Dressing or Bandage" => Some(DressingOrBandage),
"Miscellaneous Unspecified" => Some(MiscellaneousUnspecified),
_ => None,
}
}
}
}
impl Serialize for DosageFormCode {
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 = DosageFormCode;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Dosage Form Code")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
DosageFormCode::from_description(v)
.ok_or_else(|| E::custom(format!("Invalid Dosage Form Code: {}", v)))
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
DosageFormCode::from_code(v)
.ok_or_else(|| E::custom(
format!("Invalid Dosage Form Code: {}", std::str::from_utf8(v).unwrap()),
))
}
}
impl<'de> Deserialize<'de> for DosageFormCode {
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)
}
}
}