use libc::{c_void, size_t}; use std::ffi::CString; use std::ptr; use crate::libssv::SSV_LireDroitsVitale; use crate::ssv_memory::{decode_ssv_memory, Block}; #[derive(Debug, Default)] pub struct CarteVitale { donneesAssure: DonneesAssure, serviceAMOFamille: ServiceAMOFamille, donneesAccidentTravail: DonneesAccidentTravail, donneesBeneficiaire: Vec, } // 1. CB = Caractères Binaires » // 2. CE = Caractères « Etendus » (ISO 8859-1) // 3. CA = Caractères Alphanumériques (ASCII?) // 4. CN = Caractères Numériques #[derive(Debug, Default)] struct DonneesAssure { type_de_carte_vitale: char, // CA numero_de_serie: String, // CN - 1 -> 20 date_de_fin_de_validite: String, // CN - Format AAAAMMJJ0000 donnees_administration_ruf1: char, // CN donnees_administration_ruf2: String, // CA - 24 donnees_ruf_administration: String, // CE - 10 type_d_identification_du_porteur: char, // CA numero_national_d_immatriculation: String, // CA - 13 cle_du_nir: String, // CA - 2 code_regime: String, // CN - 2 caisse_gestionnaire: String, // CN - 3 centre_gestionnaire: String, // CN - 4 code_gestion: String, // CA - 2 donnees_ruf_famille: String, // CE - 55 } #[derive(Debug, Default)] struct ServiceAMOFamille { code_service_amo_famille: String, // CN - 2 date_de_debut_service_amo_famille: String, // CN - Format AAAAMMJJ0000 date_de_fin_service_amo_famille: String, // CN - Format AAAAMMJJ0000 } #[derive(Debug, Default)] struct DonneesAccidentTravail { organisme_gestionnaire_risque_at: String, // CN - 9 code_at: char, // CA - 2 identifiant_at: String, // CN - 9 organisme_gestionnaire_at1: String, // CN - 9 code_at1: char, // CA - 2 identifiant_at1: String, // CN - 9 organisme_gestionnaire_at2: String, // CN - 9 code_at2: char, // CA - 2 identifiant_at2: String, // CN - 9 } #[derive(Debug, Default)] struct DonneesBeneficiaire { nom_usuel: String, // CE - 27 nom_de_famille: String, // CE - 27 prenom: String, // CE - 27 adresse_ligne_1: String, // CE - 32 adresse_ligne_2: String, // CE - 32 adresse_ligne_3: String, // CE - 32 adresse_ligne_4: String, // CE - 32 adresse_ligne_5: String, // CE - 32 nir_certifie: String, // CA - 13 cle_du_nir_certifie: String, // CN - 2 date_de_certification_du_nir: String, // CN - Format AAAAMMJJ0000 date_de_naissance: String, // CN - Format AAAAMMJJ0000 rang_de_naissance: String, // CN - 1 qualite: String, // CN - 2 code_service_amo_beneficiaire: char, // CA - 2 date_de_debut_service_amo: String, // CN - Format AAAAMMJJ0000 date_de_fin_service_amo: String, // CN - Format AAAAMMJJ0000 donnees_ruf_amo: String, // CE - 30 periodeDroitsAMO: Vec, periodeCodeCouverture: Vec, donneesMutuelle: DonneesMutuelle, donneesComplementaire: DonneesComplementaire, donneesRUFBeneficiaireComplementaire: DonneesRUFBeneficiaireComplementaire, } #[derive(Debug, Default)] struct PeriodeDroitsAMO { date_de_debut_droits_amo: String, // CN - Format AAAAMMJJ0000 date_de_fin_droits_amo: String, // CN - Format AAAAMMJJ0000 } #[derive(Debug, Default)] struct PeriodeCodeCouverture { date_de_debut_code_couverture: String, // CN - Format AAAAMMJJ0000 date_de_fin_code_couverture: String, // CN - Format AAAAMMJJ0000 code_ald: String, // CN - 1 code_situation: String, // CN - 4 } #[derive(Debug, Default)] struct DonneesMutuelle { identification_mutuelle: String, // CN - 8 garanties_effectives: String, // CA - 8 indicateur_de_traitement_mutuelle: String, // CN - 2 type_de_services_associes: char, // CA - 1 services_associes_au_contrat: String, // CA - 17 code_aiguillage_sts: char, // CA - 1 periodeDroitsMutuelle: Vec, } #[derive(Debug, Default)] struct PeriodeDroitsMutuelle { date_de_debut_droits_mutuelle: String, // CN - Format AAAAMMJJ0000 date_de_fin_droits_mutuelle: String, // CN - Format AAAAMMJJ0000 } #[derive(Debug, Default)] struct DonneesComplementaire { numero_complementaire_b2: String, // CA - 10 numero_complementaire_edi: String, // CA - 19 numero_adherent_amc: String, // CA - 8 indicateur_de_traitement_amc: String, // CN - 2 date_de_debut_validite_amc: String, // CN - Format AAAAMMJJ0000 date_de_fin_validite_amc: String, // CN - Format AAAAMMJJ0000 code_routage_flux_amc: String, // CA - 2 identifiant_hote: String, // CA - 3 nom_de_domaine_amc: String, // CE - 20 code_aiguillage_sts: char, // CA - 1 type_de_services_associes: char, // CA - 1 services_associes_au_contrat: String, // CE - 17 } #[derive(Debug, Default)] struct DonneesRUFBeneficiaireComplementaire { donnees_ruf_beneficiaire_complementaire: String, // CE - 115 } pub fn LireDroitsVitale( lecteurPS: &str, lecteurVitale: &str, codePorteurPS: &str, dateConsultation: &str, ) -> Result { let resource_ps = CString::new(lecteurPS).expect("CString::new failed"); let resource_vitale = CString::new(lecteurVitale).expect("CString::new failed"); let card_number = CString::new(codePorteurPS).expect("CString::new failed"); let date_consultation = CString::new(dateConsultation).expect("CString::new failed"); let mut buffer: *mut c_void = ptr::null_mut(); let mut size: size_t = 0; let mut hex_values: &[u8] = &[]; unsafe { let result = SSV_LireDroitsVitale( resource_ps.as_ptr(), resource_vitale.as_ptr(), card_number.as_ptr(), date_consultation.as_ptr(), &mut buffer, &mut size, ); println!("SSV_LireDroitsVitale result: {}", result); if !buffer.is_null() { hex_values = std::slice::from_raw_parts(buffer as *const u8, size); } } let groups = decode_ssv_memory(hex_values, hex_values.len()); let OUT = decode_carte_vitale(groups); unsafe { if !buffer.is_null() { libc::free(buffer); // ??? si liberer avant decode_ssv_memory et decode_carte_vitale alors hex_values n'est plus correct ??? } } OUT } fn decode_carte_vitale(groups: Vec) -> Result { let mut cartevitale = CarteVitale::default(); for group in groups { for field in group.content { match (group.id, field.id) { (104, 1) => { cartevitale .donneesBeneficiaire .push(DonneesBeneficiaire::default()); } (105, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .periodeDroitsAMO .push(PeriodeDroitsAMO::default()); } (106, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .periodeCodeCouverture .push(PeriodeCodeCouverture::default()); } (108, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesMutuelle .periodeDroitsMutuelle .push(PeriodeDroitsMutuelle::default()); } _ => {} } if field.content.len() > 0 { match (group.id, field.id) { (101, 1) => { let byte = field.content[0]; cartevitale.donneesAssure.type_de_carte_vitale = byte as char; } (101, 2) => { cartevitale.donneesAssure.numero_de_serie = //bytes_to_decimal_string(&field.content); String::from_utf8_lossy(field.content).to_string(); } (101, 3) => { cartevitale.donneesAssure.date_de_fin_de_validite = String::from_utf8_lossy(field.content).to_string(); } (101, 4) => { println!("101.4 field.size: {:#?}", field.size); let byte = field.content[0]; cartevitale.donneesAssure.donnees_administration_ruf1 = byte as char; } (101, 5) => { cartevitale.donneesAssure.donnees_administration_ruf2 = String::from_utf8_lossy(field.content).to_string(); } (101, 6) => { cartevitale.donneesAssure.donnees_ruf_administration = String::from_utf8_lossy(field.content).to_string(); } (101, 7) => { let byte = field.content[0]; cartevitale.donneesAssure.type_d_identification_du_porteur = byte as char; } (101, 8) => { cartevitale.donneesAssure.numero_national_d_immatriculation = String::from_utf8_lossy(field.content).to_string(); } (101, 9) => { cartevitale.donneesAssure.cle_du_nir = String::from_utf8_lossy(field.content).to_string(); } (101, 10) => { cartevitale.donneesAssure.code_regime = String::from_utf8_lossy(field.content).to_string(); } (101, 11) => { cartevitale.donneesAssure.caisse_gestionnaire = String::from_utf8_lossy(field.content).to_string(); } (101, 12) => { cartevitale.donneesAssure.centre_gestionnaire = String::from_utf8_lossy(field.content).to_string(); } (101, 13) => { cartevitale.donneesAssure.code_gestion = String::from_utf8_lossy(field.content).to_string(); } (101, 14) => { cartevitale.donneesAssure.donnees_ruf_famille = String::from_utf8_lossy(field.content).to_string(); } (102, 1) => { cartevitale.serviceAMOFamille.code_service_amo_famille = String::from_utf8_lossy(field.content).to_string(); } (102, 2) => { cartevitale .serviceAMOFamille .date_de_debut_service_amo_famille = String::from_utf8_lossy(field.content).to_string(); } (102, 3) => { cartevitale .serviceAMOFamille .date_de_fin_service_amo_famille = String::from_utf8_lossy(field.content).to_string(); } (103, 1) => { cartevitale .donneesAccidentTravail .organisme_gestionnaire_risque_at = String::from_utf8_lossy(field.content).to_string(); } (103, 2) => { let byte = field.content[0]; cartevitale.donneesAccidentTravail.code_at = byte as char; } (103, 3) => { cartevitale.donneesAccidentTravail.identifiant_at = String::from_utf8_lossy(field.content).to_string(); } (103, 4) => { cartevitale .donneesAccidentTravail .organisme_gestionnaire_at1 = String::from_utf8_lossy(field.content).to_string(); } (103, 5) => { let byte = field.content[0]; cartevitale.donneesAccidentTravail.code_at1 = byte as char; } (103, 6) => { cartevitale.donneesAccidentTravail.identifiant_at1 = String::from_utf8_lossy(field.content).to_string(); } (103, 7) => { cartevitale .donneesAccidentTravail .organisme_gestionnaire_at2 = String::from_utf8_lossy(field.content).to_string(); } (103, 8) => { let byte = field.content[0]; cartevitale.donneesAccidentTravail.code_at2 = byte as char; } (103, 9) => { cartevitale.donneesAccidentTravail.identifiant_at2 = String::from_utf8_lossy(field.content).to_string(); } (104, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .nom_usuel = String::from_utf8_lossy(field.content).to_string(); } (104, 2) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .nom_de_famille = String::from_utf8_lossy(field.content).to_string(); } (104, 3) => { cartevitale.donneesBeneficiaire.last_mut().unwrap().prenom = String::from_utf8_lossy(field.content).to_string(); } (104, 4) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .adresse_ligne_1 = String::from_utf8_lossy(field.content).to_string(); } (104, 5) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .adresse_ligne_2 = String::from_utf8_lossy(field.content).to_string(); } (104, 6) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .adresse_ligne_3 = String::from_utf8_lossy(field.content).to_string(); } (104, 7) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .adresse_ligne_4 = String::from_utf8_lossy(field.content).to_string(); } (104, 8) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .adresse_ligne_5 = String::from_utf8_lossy(field.content).to_string(); } (104, 9) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .nir_certifie = String::from_utf8_lossy(field.content).to_string(); } (104, 10) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .cle_du_nir_certifie = String::from_utf8_lossy(field.content).to_string(); } (104, 11) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .date_de_certification_du_nir = String::from_utf8_lossy(field.content).to_string(); } (104, 12) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .date_de_naissance = String::from_utf8_lossy(field.content).to_string(); } (104, 13) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .rang_de_naissance = String::from_utf8_lossy(field.content).to_string(); } (104, 14) => { cartevitale.donneesBeneficiaire.last_mut().unwrap().qualite = String::from_utf8_lossy(field.content).to_string(); } (104, 15) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .code_service_amo_beneficiaire = field.content[0] as char; } (104, 16) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .date_de_debut_service_amo = String::from_utf8_lossy(field.content).to_string(); } (104, 17) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .date_de_fin_service_amo = String::from_utf8_lossy(field.content).to_string(); } (104, 18) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donnees_ruf_amo = String::from_utf8_lossy(field.content).to_string(); } (105, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .periodeDroitsAMO .last_mut() .unwrap() .date_de_debut_droits_amo = String::from_utf8_lossy(field.content).to_string(); } (105, 2) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .periodeDroitsAMO .last_mut() .unwrap() .date_de_fin_droits_amo = String::from_utf8_lossy(field.content).to_string(); } (106, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .periodeCodeCouverture .last_mut() .unwrap() .date_de_debut_code_couverture = String::from_utf8_lossy(field.content).to_string(); } (106, 2) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .periodeCodeCouverture .last_mut() .unwrap() .date_de_fin_code_couverture = String::from_utf8_lossy(field.content).to_string(); } (106, 3) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .periodeCodeCouverture .last_mut() .unwrap() .code_ald = String::from_utf8_lossy(field.content).to_string(); } (106, 4) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .periodeCodeCouverture .last_mut() .unwrap() .code_situation = String::from_utf8_lossy(field.content).to_string(); } (107, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesMutuelle .identification_mutuelle = String::from_utf8_lossy(field.content).to_string(); } (107, 2) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesMutuelle .garanties_effectives = String::from_utf8_lossy(field.content).to_string(); } (107, 3) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesMutuelle .indicateur_de_traitement_mutuelle = String::from_utf8_lossy(field.content).to_string(); } (107, 4) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesMutuelle .type_de_services_associes = field.content[0] as char; } (107, 5) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesMutuelle .services_associes_au_contrat = String::from_utf8_lossy(field.content).to_string(); } (107, 6) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesMutuelle .code_aiguillage_sts = field.content[0] as char; } (108, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesMutuelle .periodeDroitsMutuelle .last_mut() .unwrap() .date_de_debut_droits_mutuelle = String::from_utf8_lossy(field.content).to_string(); } (108, 2) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesMutuelle .periodeDroitsMutuelle .last_mut() .unwrap() .date_de_fin_droits_mutuelle = String::from_utf8_lossy(field.content).to_string(); } (109, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .numero_complementaire_b2 = String::from_utf8_lossy(field.content).to_string(); } (109, 2) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .numero_complementaire_edi = String::from_utf8_lossy(field.content).to_string(); } (109, 3) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .numero_adherent_amc = String::from_utf8_lossy(field.content).to_string(); } (109, 4) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .indicateur_de_traitement_amc = String::from_utf8_lossy(field.content).to_string(); } (109, 5) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .date_de_debut_validite_amc = String::from_utf8_lossy(field.content).to_string(); } (109, 6) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .date_de_fin_validite_amc = String::from_utf8_lossy(field.content).to_string(); } (109, 7) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .code_routage_flux_amc = String::from_utf8_lossy(field.content).to_string(); } (109, 8) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .identifiant_hote = String::from_utf8_lossy(field.content).to_string(); } (109, 9) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .nom_de_domaine_amc = String::from_utf8_lossy(field.content).to_string(); } (109, 10) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .code_aiguillage_sts = field.content[0] as char; } (109, 11) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .type_de_services_associes = field.content[0] as char; } (109, 12) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesComplementaire .services_associes_au_contrat = String::from_utf8_lossy(field.content).to_string(); } (111, 1) => { cartevitale .donneesBeneficiaire .last_mut() .unwrap() .donneesRUFBeneficiaireComplementaire .donnees_ruf_beneficiaire_complementaire = String::from_utf8_lossy(field.content).to_string(); } _ => { return Err(format!( "Unknown (group, field) pair: ({}, {})", group.id, field.id )) } } } } } Ok(cartevitale) } // #[cfg(test)] // mod test_decode_carte_ps { // use super::*; // #[test] // fn test_francoise_pharmacien0052419() { // let bytes: &[u8] = &[ // 0, 1, 51, // Block 01, Content size 51 // 1, 48, // Field 01, Content size 1 // 1, 56, // Field 02, Content size 1 // 11, 57, 57, 55, 48, 48, 53, 50, 52, 49, 57, 52, // Field 03, Content size 11 // 1, 52, // Field 04, Content size 1 // 2, 50, 50, // Field 05, Content size 2 // 17, 80, 72, 65, 82, 77, 65, 67, 73, 69, 78, 48, 48, 53, 50, 52, 49, // 57, // Field 06, Content size 17 // 9, 70, 82, 65, 78, 67, 79, 73, 83, 69, // Field 07, Content size 9 // 1, 84, // Field 08, Content size 1 // 0, 2, 83, // Block 02, Content size 83 // 1, 1, 1, 48, 1, 49, 2, 56, 54, 1, 49, 9, 48, 66, 48, 50, 50, 49, 57, 53, 56, 1, 56, 24, // 80, 72, 65, 82, 77, 65, 67, 73, 69, 32, 68, 85, 32, 67, 69, 78, 84, 82, 69, 50, 50, 49, // 57, 53, 8, 48, 48, 50, 48, 50, 52, 49, 57, 1, 56, 0, 1, 48, 1, 49, 2, 53, 48, 2, 49, // 48, 2, 48, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, // ]; // let blocks = decode_ssv_memory(bytes, bytes.len()); // let carte_ps = decode_carte_ps(blocks).unwrap(); // assert_eq!(carte_ps.titulaire.type_de_carte_ps, "0"); // assert_eq!(carte_ps.titulaire.type_d_identification_nationale, "8"); // assert_eq!( // carte_ps.titulaire.numero_d_identification_nationale, // "99700524194" // ); // assert_eq!( // carte_ps.titulaire.cle_du_numero_d_identification_nationale, // "4" // ); // assert_eq!(carte_ps.titulaire.code_civilite, "22"); // assert_eq!(carte_ps.titulaire.nom_du_ps, "PHARMACIEN0052419"); // assert_eq!(carte_ps.titulaire.prenom_du_ps, "FRANCOISE"); // assert_eq!(carte_ps.titulaire.categorie_carte, 'T'); // assert_eq!(carte_ps.situations.len(), 1); // assert_eq!( // carte_ps.situations[0].numero_logique_de_la_situation_de_facturation_du_ps, // 1 // ); // assert_eq!(carte_ps.situations[0].mode_d_exercice, "0"); // assert_eq!(carte_ps.situations[0].statut_d_exercice, "1"); // assert_eq!(carte_ps.situations[0].secteur_d_activite, "86"); // assert_eq!(carte_ps.situations[0].type_d_identification_structure, "1"); // assert_eq!( // carte_ps.situations[0].numero_d_identification_structure, // "0B0221958" // ); // assert_eq!( // carte_ps.situations[0].cle_du_numero_d_identification_structure, // "8" // ); // assert_eq!( // carte_ps.situations[0].raison_sociale_structure, // "PHARMACIE DU CENTRE22195" // ); // assert_eq!( // carte_ps.situations[0].numero_d_identification_de_facturation_du_ps, // "00202419" // ); // assert_eq!( // carte_ps.situations[0].cle_du_numero_d_identification_de_facturation_du_ps, // "8" // ); // assert_eq!( // carte_ps.situations[0].numero_d_identification_du_ps_remplaçant, // "" // ); // assert_eq!( // carte_ps.situations[0].cle_du_numero_d_identification_du_ps_remplaçant, // "0" // ); // assert_eq!(carte_ps.situations[0].code_conventionnel, "1"); // assert_eq!(carte_ps.situations[0].code_specialite, "50"); // assert_eq!(carte_ps.situations[0].code_zone_tarifaire, "10"); // assert_eq!(carte_ps.situations[0].code_zone_ik, "00"); // assert_eq!(carte_ps.situations[0].code_agrement_1, "0"); // assert_eq!(carte_ps.situations[0].code_agrement_2, "0"); // assert_eq!(carte_ps.situations[0].code_agrement_3, "0"); // assert_eq!( // carte_ps.situations[0].habilitation_à_signer_une_facture, // "1" // ); // assert_eq!(carte_ps.situations[0].habilitation_à_signer_un_lot, "1"); // } // #[test] // fn test_multiple_situations() { // let bytes: &[u8] = &[ // 0, 1, 51, // Block 01, Content size 51 // 1, 48, 1, 56, 11, 57, 57, 55, 48, 48, 53, 50, 52, 49, 57, 52, 1, 52, 2, 50, 50, 17, 80, // 72, 65, 82, 77, 65, 67, 73, 69, 78, 48, 48, 53, 50, 52, 49, 57, 9, 70, 82, 65, 78, 67, // 79, 73, 83, 69, 1, 84, 0, 2, 83, // Block 02, Content size 83 // 1, 1, 1, 48, 1, 49, 2, 56, 54, 1, 49, 9, 48, 66, 48, 50, 50, 49, 57, 53, 56, 1, 56, 24, // 80, 72, 65, 82, 77, 65, 67, 73, 69, 32, 68, 85, 32, 67, 69, 78, 84, 82, 69, 50, 50, 49, // 57, 53, 8, 48, 48, 50, 48, 50, 52, 49, 57, 1, 56, 0, 1, 48, 1, 49, 2, 53, 48, 2, 49, // 48, 2, 48, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 0, 3, // 83, // Block 03, Content size 83 // 1, 1, 1, 48, 1, 49, 2, 56, 54, 1, 49, 9, 48, 66, 48, 50, 50, 49, 57, 53, 56, 1, 56, 24, // 80, 72, 65, 82, 77, 65, 67, 73, 69, 32, 68, 85, 32, 67, 69, 78, 84, 82, 69, 50, 50, 49, // 57, 53, 8, 48, 48, 50, 48, 50, 52, 49, 57, 1, 56, 0, 1, 48, 1, 49, 2, 53, 48, 2, 49, // 48, 2, 48, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 0, 4, // 83, // Block 04, Content size 83 // 1, 1, 1, 48, 1, 49, 2, 56, 54, 1, 49, 9, 48, 66, 48, 50, 50, 49, 57, 53, 56, 1, 56, 24, // 80, 72, 65, 82, 77, 65, 67, 73, 69, 32, 68, 85, 32, 67, 69, 78, 84, 82, 69, 50, 50, 49, // 57, 53, 8, 48, 48, 50, 48, 50, 52, 49, 57, 1, 56, 0, 1, 48, 1, 49, 2, 53, 48, 2, 49, // 48, 2, 48, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, // ]; // let blocks = decode_ssv_memory(bytes, bytes.len()); // let carte_ps = decode_carte_ps(blocks).unwrap(); // assert_eq!(carte_ps.situations.len(), 3); // assert_eq!( // carte_ps.situations[0].raison_sociale_structure, // "PHARMACIE DU CENTRE22195" // ); // assert_eq!( // carte_ps.situations[1].raison_sociale_structure, // "PHARMACIE DU CENTRE22195" // ); // assert_eq!( // carte_ps.situations[2].raison_sociale_structure, // "PHARMACIE DU CENTRE22195" // ); // } // #[test] // #[should_panic] // fn test_missing_field() { // todo!(); // } // #[test] // #[should_panic] // fn test_unknown_group_field_pair() { // todo!(); // } // #[test] // #[should_panic] // fn test_invalid_field_format() { // todo!(); // } // }