use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "fn", rename_all = "snake_case")]
pub enum Transform {
Trim,
CollapseWhitespace,
DigitsOnly,
Upper,
Lower,
MoneyToCents {
#[serde(default = "default_scale")]
scale: u8,
},
DateParse {
format: String,
},
Replace {
pattern: String,
replacement: String,
},
Default {
value: serde_json::Value,
},
PhoneUs,
PhoneE164,
NormalizeFlightNumber,
NormalizeIcd10,
NormalizeCpt,
NormalizeHcpcs,
NormalizeNdc11,
CardMaskLast4,
FormatSsn,
FormatEin,
MaskSsn,
MaskEin,
FormatIban,
FormatCreditCard,
FormatThousands {
#[serde(default = "default_separator")]
separator: String,
},
FormatDecimal {
places: u8,
},
}
fn default_scale() -> u8 {
2
}
fn default_separator() -> String {
",".to_string()
}
impl Transform {
pub fn trim() -> Self {
Self::Trim
}
pub fn digits_only() -> Self {
Self::DigitsOnly
}
pub fn upper() -> Self {
Self::Upper
}
pub fn lower() -> Self {
Self::Lower
}
pub fn money_to_cents() -> Self {
Self::MoneyToCents { scale: 2 }
}
pub fn money_to_cents_with_scale(scale: u8) -> Self {
Self::MoneyToCents { scale }
}
pub fn date_parse(format: impl Into<String>) -> Self {
Self::DateParse {
format: format.into(),
}
}
pub fn collapse_whitespace() -> Self {
Self::CollapseWhitespace
}
pub fn replace(pattern: impl Into<String>, replacement: impl Into<String>) -> Self {
Self::Replace {
pattern: pattern.into(),
replacement: replacement.into(),
}
}
pub fn default_value(value: serde_json::Value) -> Self {
Self::Default { value }
}
pub fn phone_us() -> Self {
Self::PhoneUs
}
pub fn phone_e164() -> Self {
Self::PhoneE164
}
pub fn normalize_flight_number() -> Self {
Self::NormalizeFlightNumber
}
pub fn normalize_icd10() -> Self {
Self::NormalizeIcd10
}
pub fn normalize_cpt() -> Self {
Self::NormalizeCpt
}
pub fn normalize_hcpcs() -> Self {
Self::NormalizeHcpcs
}
pub fn normalize_ndc11() -> Self {
Self::NormalizeNdc11
}
pub fn card_mask_last4() -> Self {
Self::CardMaskLast4
}
pub fn format_ssn() -> Self {
Self::FormatSsn
}
pub fn format_ein() -> Self {
Self::FormatEin
}
pub fn mask_ssn() -> Self {
Self::MaskSsn
}
pub fn mask_ein() -> Self {
Self::MaskEin
}
pub fn format_iban() -> Self {
Self::FormatIban
}
pub fn format_credit_card() -> Self {
Self::FormatCreditCard
}
pub fn format_thousands() -> Self {
Self::FormatThousands {
separator: ",".to_string(),
}
}
pub fn format_thousands_with_separator(separator: impl Into<String>) -> Self {
Self::FormatThousands {
separator: separator.into(),
}
}
pub fn format_decimal(places: u8) -> Self {
Self::FormatDecimal { places }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serde_trim() {
let t = Transform::trim();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"trim"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_money_to_cents() {
let t = Transform::money_to_cents_with_scale(3);
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"money_to_cents","scale":3}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_money_to_cents_default_scale() {
let json = r#"{"fn":"money_to_cents"}"#;
let parsed: Transform = serde_json::from_str(json).unwrap();
assert_eq!(parsed, Transform::MoneyToCents { scale: 2 });
}
#[test]
fn test_serde_date_parse() {
let t = Transform::date_parse("%m/%d/%Y");
let json = serde_json::to_string(&t).unwrap();
assert!(json.contains("date_parse"));
assert!(json.contains("%m/%d/%Y"));
}
#[test]
fn test_serde_replace() {
let t = Transform::replace("-", "");
let json = serde_json::to_string(&t).unwrap();
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_phone_us() {
let t = Transform::phone_us();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"phone_us"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_phone_e164() {
let t = Transform::phone_e164();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"phone_e164"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_normalize_flight_number() {
let t = Transform::normalize_flight_number();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"normalize_flight_number"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_normalize_icd10() {
let t = Transform::normalize_icd10();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"normalize_icd10"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_normalize_cpt() {
let t = Transform::normalize_cpt();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"normalize_cpt"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_normalize_hcpcs() {
let t = Transform::normalize_hcpcs();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"normalize_hcpcs"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_normalize_ndc11() {
let t = Transform::normalize_ndc11();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"normalize_ndc11"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_card_mask_last4() {
let t = Transform::card_mask_last4();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"card_mask_last4"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_format_ssn() {
let t = Transform::format_ssn();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"format_ssn"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_format_ein() {
let t = Transform::format_ein();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"format_ein"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_mask_ssn() {
let t = Transform::mask_ssn();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"mask_ssn"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_mask_ein() {
let t = Transform::mask_ein();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"mask_ein"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_format_iban() {
let t = Transform::format_iban();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"format_iban"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_format_credit_card() {
let t = Transform::format_credit_card();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"format_credit_card"}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_format_thousands() {
let t = Transform::format_thousands();
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"format_thousands","separator":","}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
#[test]
fn test_serde_format_thousands_default_separator() {
let json = r#"{"fn":"format_thousands"}"#;
let parsed: Transform = serde_json::from_str(json).unwrap();
assert_eq!(
parsed,
Transform::FormatThousands {
separator: ",".to_string()
}
);
}
#[test]
fn test_serde_format_decimal() {
let t = Transform::format_decimal(2);
let json = serde_json::to_string(&t).unwrap();
assert_eq!(json, r#"{"fn":"format_decimal","places":2}"#);
let parsed: Transform = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, t);
}
}