From 3dddd689138683e18808852218bbd01f3e2b33c3 Mon Sep 17 00:00:00 2001
From: Anthony Graignic <anthony.graignic@uca.fr>
Date: Fri, 19 Jan 2024 10:15:39 +0100
Subject: [PATCH 1/2] Add support for new dataset from MyBus

Add `validation_datetime` column in CSV
Update MobilityRecord
Add csv read tests
Add new dataset extract
---
 data/dataset-extract.csv   |  14 +++---
 data/sample-2-extract.csv  | 100 +++++++++++++++++++++++++++++++++++++
 src/utils/mobility_data.rs |  44 +++++++++++-----
 3 files changed, 138 insertions(+), 20 deletions(-)
 create mode 100644 data/sample-2-extract.csv

diff --git a/data/dataset-extract.csv b/data/dataset-extract.csv
index a74a11e..7d92a8c 100644
--- a/data/dataset-extract.csv
+++ b/data/dataset-extract.csv
@@ -1,7 +1,7 @@
-id,user_id,network,service,label,created_at,from_coord,from_label,from_datetime,to_coord,to_label,to_datetime,from_latitude,from_longitude,to_latitude,to_longitude
-0,79,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel 26-64 ans, 1 passager(s)",2023-05-31T22:09:51.226773Z,,,2023-06-01T00:09:50.000Z,,,,,,,
-1,901,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel - de 26 ans, 1 passager(s)",2023-05-31T22:12:24.054056Z,,,2023-06-01T00:12:23.000Z,,,,,,,
-2,4037,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel - de 26 ans, 1 passager(s)",2023-05-31T22:22:14.465196Z,,,2023-06-01T00:22:13.000Z,,,,,,,
-3,4638,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel - de 26 ans, 1 passager(s)",2023-06-01T00:21:37.066224Z,,,2023-06-01T02:21:36.000Z,,,,,,,
-12,4272,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel - de 26 ans, 1 passager(s)",2023-06-01T04:03:48.286701Z,,,2023-06-01T06:03:47.000Z,,,,,,,
-10653,79,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel 26-64 ans, 1 passager(s)",2023-07-02T19:02:04.987621Z,,,2023-07-02T21:02:04.000Z,,,,,,,
\ No newline at end of file
+id,user_id,network,service,label,created_at,validation_datetime,from_coord,from_label,from_datetime,to_coord,to_label,to_datetime,from_latitude,from_longitude,to_latitude,to_longitude
+0,79,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel 26-64 ans, 1 passager(s)",2023-05-31T22:09:51.226773Z,,,,2023-06-01T00:09:50.000Z,,,,,,,
+1,901,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel - de 26 ans, 1 passager(s)",2023-05-31T22:12:24.054056Z,,,,2023-06-01T00:12:23.000Z,,,,,,,
+2,4037,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel - de 26 ans, 1 passager(s)",2023-05-31T22:22:14.465196Z,,,,2023-06-01T00:22:13.000Z,,,,,,,
+3,4638,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel - de 26 ans, 1 passager(s)",2023-06-01T00:21:37.066224Z,,,,2023-06-01T02:21:36.000Z,,,,,,,
+12,4272,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel - de 26 ans, 1 passager(s)",2023-06-01T04:03:48.286701Z,,,,2023-06-01T06:03:47.000Z,,,,,,,
+10653,79,mulhouse,PUBLIC_TRANSPORT,"Abonnement mensuel 26-64 ans, 1 passager(s)",2023-07-02T19:02:04.987621Z,,,,2023-07-02T21:02:04.000Z,,,,,,,
\ No newline at end of file
diff --git a/data/sample-2-extract.csv b/data/sample-2-extract.csv
new file mode 100644
index 0000000..d865e5b
--- /dev/null
+++ b/data/sample-2-extract.csv
@@ -0,0 +1,100 @@
+id,user_id,network,service,label,created_at,validation_datetime,from_coord,from_label,from_datetime,to_coord,to_label,to_datetime,from_latitude,from_longitude,to_latitude,to_longitude
+23,5678,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-01T04:27:58+01:00,2023-06-01T04:28:55+01:00,,,,,,,,,,
+88,10225,city-B,PUBLIC_TRANSPORT,Journée 1 Personne,2023-06-01T05:14:14+01:00,2023-06-01T05:14:22+01:00,,,,,,,,,,
+222,20086,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-01T05:48:39+01:00,2023-06-01T05:51:16+01:00,,,,,,,,,,
+256,41838,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T05:57:27+01:00,2023-06-01T06:01:37+01:00,,,,,,,,,,
+403,4575,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T06:19:44+01:00,2023-06-01T06:35:30+01:00,,,,,,,,,,
+460,37746,city-A,PUBLIC_TRANSPORT,Pass Juin 2023,2023-06-01T05:50:45+01:00,2023-06-01T06:49:13+01:00,,,,,,,,,,
+517,15463,city-D,PUBLIC_TRANSPORT,Ticket unité,2023-06-01T07:07:17+01:00,2023-06-01T07:07:38+01:00,,,,,,,,,,
+761,39893,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T09:12:44+01:00,2023-06-01T09:14:50+01:00,,,,,,,,,,
+788,24020,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T06:28:48+01:00,2023-06-01T09:27:37+01:00,,,,,,,,,,
+1023,47809,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T10:41:04+01:00,2023-06-01T10:46:45+01:00,,,,,,,,,,
+1199,17527,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-01T11:55:13+01:00,2023-06-01T11:55:27+01:00,,,,,,,,,,
+1203,52315,city-A,PUBLIC_TRANSPORT, 1,2023-06-01T11:50:22+01:00,2023-06-01T11:56:56+01:00,,,,,,,,,,
+1288,50881,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-01T12:29:57+01:00,2023-06-01T12:30:25+01:00,,,,,,,,,,
+1811,40541,city-C,PUBLIC_TRANSPORT,Titre Unitaire,2023-06-01T14:57:35+01:00,2023-06-01T14:59:27+01:00,,,,,,,,,,
+1906,1309,city-C,PUBLIC_TRANSPORT,Titre Unitaire,2023-06-01T15:13:40+01:00,2023-06-01T15:17:37+01:00,,,,,,,,,,
+1987,24233,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-01T15:22:03+01:00,2023-06-01T15:31:55+01:00,,,,,,,,,,
+2008,25876,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-01T15:36:36+01:00,2023-06-01T15:36:45+01:00,,,,,,,,,,
+2034,51636,city-C,PUBLIC_TRANSPORT,Abonnement Mensuel Jeune Juin,2023-06-01T10:12:31+01:00,2023-06-01T15:40:22+01:00,,,,,,,,,,
+2041,26472,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-01T15:42:12+01:00,2023-06-01T15:42:22+01:00,,,,,,,,,,
+2043,1004,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T15:41:25+01:00,2023-06-01T15:42:28+01:00,,,,,,,,,,
+2049,18536,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T15:22:41+01:00,2023-06-01T15:42:49+01:00,,,,,,,,,,
+2087,32509,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T14:25:13+01:00,2023-06-01T15:49:57+01:00,,,,,,,,,,
+2187,18903,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T15:50:47+01:00,2023-06-01T16:09:51+01:00,,,,,,,,,,
+2253,4357,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-01T16:21:05+01:00,2023-06-01T16:21:40+01:00,,,,,,,,,,
+2361,32217,city-A,PUBLIC_TRANSPORT,Pass Juin 2023,2023-06-01T16:54:04+01:00,2023-06-01T16:54:21+01:00,,,,,,,,,,
+2447,8602,city-A,PUBLIC_TRANSPORT,Pass 24h,2023-06-01T11:52:55+01:00,2023-06-01T17:23:20+01:00,,,,,,,,,,
+2484,50313,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-01T17:37:16+01:00,2023-06-01T17:39:54+01:00,,,,,,,,,,
+2756,20764,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-02T04:53:08+01:00,2023-06-02T05:00:15+01:00,,,,,,,,,,
+2820,40861,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-02T05:13:53+01:00,2023-06-02T05:22:08+01:00,,,,,,,,,,
+2858,30883,city-E,PUBLIC_TRANSPORT,Abonnement Juin Tout Public,2023-06-02T05:31:31+01:00,2023-06-02T05:32:02+01:00,,,,,,,,,,
+2864,26609,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-02T04:30:26+01:00,2023-06-02T05:32:51+01:00,,,,,,,,,,
+2907,42219,city-A,PUBLIC_TRANSPORT, 1,2023-06-01T06:45:10+01:00,2023-06-02T05:40:25+01:00,,,,,,,,,,
+2937,33291,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-02T05:17:42+01:00,2023-06-02T05:44:42+01:00,,,,,,,,,,
+2949,43758,city-A,PUBLIC_TRANSPORT,Pass Juin 2023,2023-06-01T05:38:58+01:00,2023-06-02T05:47:32+01:00,,,,,,,,,,
+2966,2356,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-02T05:50:48+01:00,2023-06-02T05:51:57+01:00,,,,,,,,,,
+3118,1941,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-02T06:20:50+01:00,2023-06-02T06:21:10+01:00,,,,,,,,,,
+3148,4772,city-B,PUBLIC_TRANSPORT,1 Voyage - carnet,2023-06-02T06:10:20+01:00,2023-06-02T06:26:28+01:00,,,,,,,,,,
+3500,32785,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-02T07:46:38+01:00,2023-06-02T07:54:14+01:00,,,,,,,,,,
+3593,13456,city-A,PUBLIC_TRANSPORT,Pass 24h,2023-06-02T08:18:09+01:00,2023-06-02T08:26:32+01:00,,,,,,,,,,
+3831,29116,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-02T09:45:12+01:00,2023-06-02T09:48:22+01:00,,,,,,,,,,
+3859,30474,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-02T09:53:29+01:00,2023-06-02T09:56:24+01:00,,,,,,,,,,
+4041,25611,city-D,PUBLIC_TRANSPORT,Mensuel Juin Tout Public,2023-06-01T05:41:42+01:00,2023-06-02T10:53:34+01:00,,,,,,,,,,
+4217,15390,city-E,PUBLIC_TRANSPORT,1 Voyage - carnet,2023-06-02T06:34:25+01:00,2023-06-02T11:43:43+01:00,,,,,,,,,,
+4245,9894,city-C,PUBLIC_TRANSPORT,Titre Unitaire,2023-06-02T11:45:32+01:00,2023-06-02T11:49:36+01:00,,,,,,,,,,
+4374,27618,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-02T12:17:48+01:00,2023-06-02T12:32:10+01:00,,,,,,,,,,
+4413,32937,city-A,PUBLIC_TRANSPORT, 1,2023-06-02T10:16:14+01:00,2023-06-02T12:40:36+01:00,,,,,,,,,,
+4561,21038,city-A,PUBLIC_TRANSPORT, 1,2023-06-02T04:36:12+01:00,2023-06-02T13:15:35+01:00,,,,,,,,,,
+4685,6542,city-B,PUBLIC_TRANSPORT,1 Voyage - carnet,2023-06-01T07:23:06+01:00,2023-06-02T13:47:48+01:00,,,,,,,,,,
+4800,32481,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-02T14:12:24+01:00,2023-06-02T14:13:48+01:00,,,,,,,,,,
+4810,29314,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-02T14:14:24+01:00,2023-06-02T14:14:35+01:00,,,,,,,,,,
+4904,32301,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-01T18:13:05+01:00,2023-06-02T14:31:47+01:00,,,,,,,,,,
+5024,21871,city-D,PUBLIC_TRANSPORT,Ticket unité - carnet,2023-06-01T11:17:09+01:00,2023-06-02T14:53:43+01:00,,,,,,,,,,
+5097,9832,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-02T14:29:27+01:00,2023-06-02T15:07:15+01:00,,,,,,,,,,
+5186,4768,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-02T12:01:29+01:00,2023-06-02T15:23:47+01:00,,,,,,,,,,
+5225,31397,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-02T06:33:35+01:00,2023-06-02T15:29:01+01:00,,,,,,,,,,
+5351,45562,city-A,PUBLIC_TRANSPORT,Pass Juin 2023,2023-06-01T06:26:20+01:00,2023-06-02T15:52:14+01:00,,,,,,,,,,
+5406,36261,city-A,PUBLIC_TRANSPORT,Pass Juin 2023,2023-06-01T05:48:08+01:00,2023-06-02T16:03:52+01:00,,,,,,,,,,
+5490,47077,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-02T15:27:27+01:00,2023-06-02T16:23:59+01:00,,,,,,,,,,
+5512,21639,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-01T14:03:37+01:00,2023-06-02T16:27:25+01:00,,,,,,,,,,
+5710,8875,city-C,PUBLIC_TRANSPORT,Abonnement Mensuel Jeune Juin,2023-06-02T08:24:18+01:00,2023-06-02T17:22:43+01:00,,,,,,,,,,
+5835,19369,city-A,PUBLIC_TRANSPORT,Pass 24h,2023-06-02T17:55:12+01:00,2023-06-02T18:04:09+01:00,,,,,,,,,,
+5865,26064,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-02T18:21:07+01:00,2023-06-02T18:22:04+01:00,,,,,,,,,,
+5883,12561,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-01T16:34:12+01:00,2023-06-02T18:29:27+01:00,,,,,,,,,,
+6106,20199,city-C,PUBLIC_TRANSPORT,Abonnement Mensuel Juin,2023-06-01T06:12:57+01:00,2023-06-03T06:42:47+01:00,,,,,,,,,,
+6230,10674,city-B,PUBLIC_TRANSPORT,Journée 1 Personne,2023-06-02T18:27:06+01:00,2023-06-03T08:28:15+01:00,,,,,,,,,,
+6263,1463,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-03T08:47:03+01:00,2023-06-03T08:49:26+01:00,,,,,,,,,,
+6271,21748,city-D,PUBLIC_TRANSPORT,Ticket unité,2023-06-03T08:53:21+01:00,2023-06-03T08:58:16+01:00,,,,,,,,,,
+6405,48763,city-B,PUBLIC_TRANSPORT,1 Voyage - carnet,2023-06-03T10:29:09+01:00,2023-06-03T10:29:17+01:00,,,,,,,,,,
+6449,44063,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-03T10:47:06+01:00,2023-06-03T10:59:42+01:00,,,,,,,,,,
+6473,35029,city-A,PUBLIC_TRANSPORT, 1,2023-06-03T11:15:13+01:00,2023-06-03T11:16:24+01:00,,,,,,,,,,
+6534,51493,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-02T06:42:47+01:00,2023-06-03T11:59:53+01:00,,,,,,,,,,
+6620,46583,city-C,PUBLIC_TRANSPORT,Titre Journée,2023-06-02T10:24:20+01:00,2023-06-03T12:55:22+01:00,,,,,,,,,,
+6954,52547,city-C,PUBLIC_TRANSPORT,Abonnement Mensuel Juin,2023-06-02T11:59:31+01:00,2023-06-03T16:17:47+01:00,,,,,,,,,,
+6986,2255,city-B,PUBLIC_TRANSPORT,1 Voyage - carnet,2023-06-03T16:04:56+01:00,2023-06-03T16:32:07+01:00,,,,,,,,,,
+7284,47545,city-C,PUBLIC_TRANSPORT,Titre Unitaire,2023-06-04T11:09:49+01:00,2023-06-04T11:13:18+01:00,,,,,,,,,,
+7516,3883,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-04T17:13:46+01:00,2023-06-05T04:15:16+01:00,,,,,,,,,,
+7523,14926,city-A,PUBLIC_TRANSPORT,Pass Juin 2023,2023-06-05T04:18:47+01:00,2023-06-05T04:25:28+01:00,,,,,,,,,,
+7674,29964,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-05T05:25:56+01:00,2023-06-05T05:26:08+01:00,,,,,,,,,,
+7694,33522,city-A,PUBLIC_TRANSPORT,Pass Juin 2023,2023-06-01T05:47:51+01:00,2023-06-05T05:30:10+01:00,,,,,,,,,,
+7731,43610,city-C,PUBLIC_TRANSPORT,Titre Unitaire,2023-06-05T05:35:26+01:00,2023-06-05T05:35:53+01:00,,,,,,,,,,
+8038,43065,city-E,PUBLIC_TRANSPORT,1 Voyage - carnet,2023-06-05T06:23:20+01:00,2023-06-05T06:23:31+01:00,,,,,,,,,,
+8143,18629,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-05T06:35:12+01:00,2023-06-05T06:39:14+01:00,,,,,,,,,,
+8185,40186,city-B,PUBLIC_TRANSPORT,Journée 1 Personne,2023-06-02T20:12:38+01:00,2023-06-05T06:45:39+01:00,,,,,,,,,,
+8391,7162,city-A,PUBLIC_TRANSPORT,Pass 24h,2023-06-05T07:12:14+01:00,2023-06-05T07:39:53+01:00,,,,,,,,,,
+8455,51785,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-05T07:58:03+01:00,2023-06-05T07:58:23+01:00,,,,,,,,,,
+8501,23412,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-05T08:08:18+01:00,2023-06-05T08:11:36+01:00,,,,,,,,,,
+8716,27742,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-05T06:26:41+01:00,2023-06-05T09:28:09+01:00,,,,,,,,,,
+8820,21302,city-A,PUBLIC_TRANSPORT,Pass Juin 2023,2023-06-05T04:41:37+01:00,2023-06-05T10:02:43+01:00,,,,,,,,,,
+9082,47410,city-A,PUBLIC_TRANSPORT,Pass Juin 2023,2023-06-05T10:48:54+01:00,2023-06-05T11:08:38+01:00,,,,,,,,,,
+9131,23520,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-02T10:27:13+01:00,2023-06-05T11:22:08+01:00,,,,,,,,,,
+9135,28808,city-D,PUBLIC_TRANSPORT,Ticket unité - carnet,2023-06-04T21:26:27+01:00,2023-06-05T11:23:27+01:00,,,,,,,,,,
+9180,54168,city-B,PUBLIC_TRANSPORT,1 Voyage,2023-06-05T11:10:00+01:00,2023-06-05T11:34:38+01:00,,,,,,,,,,
+9198,23002,city-D,PUBLIC_TRANSPORT,Ticket unité,2023-06-03T12:48:20+01:00,2023-06-05T11:41:26+01:00,,,,,,,,,,
+9565,23521,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-05T13:13:23+01:00,2023-06-05T13:17:53+01:00,,,,,,,,,,
+9778,39183,city-A,PUBLIC_TRANSPORT, 1 - Carnet,2023-06-04T17:39:15+01:00,2023-06-05T14:05:36+01:00,,,,,,,,,,
+9847,639,city-A,PUBLIC_TRANSPORT,Pass 1 - Carnet,2023-06-05T06:45:31+01:00,2023-06-05T14:17:11+01:00,,,,,,,,,,
+9890,29027,city-D,PUBLIC_TRANSPORT,Ticket journée,2023-06-05T09:56:47+01:00,2023-06-05T14:25:09+01:00,,,,,,,,,,
+9964,10835,city-C,PUBLIC_TRANSPORT,Titre Unitaire,2023-06-05T05:39:41+01:00,2023-06-05T14:37:41+01:00,,,,,,,,,,
+10025,51007,city-A,PUBLIC_TRANSPORT,Pass 1,2023-06-05T14:25:59+01:00,2023-06-05T14:46:13+01:00,,,,,,,,,,
diff --git a/src/utils/mobility_data.rs b/src/utils/mobility_data.rs
index 8589aec..6334d0d 100644
--- a/src/utils/mobility_data.rs
+++ b/src/utils/mobility_data.rs
@@ -7,10 +7,10 @@ use time::OffsetDateTime;
 
 /// Mobility Record from Public Transportation
 /// ---
-/// Created from data in `data/dataset-extract.csv`
+/// Created from data in `data/dataset-extract.csv` and `data/sample-2-extract.csv`
 ///
 /// CSV header:
-/// id user_id network service label created_at from_coord from_label from_datetime from_latitude from_longitude to_coord to_label to_datetime to_latitude to_longitude
+/// id,user_id,network,service,label,created_at,validation_datetime,from_coord,from_label,from_datetime,to_coord,to_label,to_datetime,from_latitude,from_longitude,to_latitude,to_longitude
 #[derive(Clone, Debug, Deserialize, Serialize)]
 pub struct MobilityRecord {
     pub id: u64,
@@ -21,6 +21,7 @@ pub struct MobilityRecord {
     // `YYYY-MM-DD HH:mm:ss.SSSSSS` rfc3339
     #[serde(with = "time::serde::rfc3339")]
     pub created_at: time::OffsetDateTime,
+
     /// Departure coordinates in hex PostGIS EWKB (Extended Well-Known Binary)
     pub from_coord: Option<String>,
     pub from_label: Option<String>,
@@ -37,6 +38,9 @@ pub struct MobilityRecord {
     pub to_datetime: Option<time::OffsetDateTime>,
     pub to_latitude: Option<f64>,
     pub to_longitude: Option<f64>,
+
+    #[serde(with = "time::serde::rfc3339::option")]
+    pub validation_datetime: Option<time::OffsetDateTime>,
 }
 
 impl MobilityRecord {
@@ -140,18 +144,19 @@ mod tests {
     use super::*;
 
     #[test]
-    fn read_csv_should_work() {
+    fn read_csv_from_str_should_work() {
         // ARRANGE
         let example_data = "\
-        id,user_id,network,service,label,created_at,from_coord,from_label,from_datetime,to_coord,to_label,to_datetime,from_latitude,from_longitude,to_latitude,to_longitude
-        10653,79,mulhouse,PUBLIC_TRANSPORT,Abo,2023-07-02T19:02:04.987621Z,DEADC0DE,TEST,2023-07-02T21:02:04.000Z,DEADC0DE,TEST,2023-07-02T21:02:04.000Z,0.0,0.0,0.0,0.0
-        ";
-        // let mut rdr = Reader::from_reader(example_data.as_bytes());
-        let mut rdr = Reader::from_path("./data/dataset-extract.csv").unwrap();
+id,user_id,network,service,label,created_at,validation_datetime,from_coord,from_label,from_datetime,to_coord,to_label,to_datetime,from_latitude,from_longitude,to_latitude,to_longitude
+400,9,A,B,C,2023-07-02T21:02:04.000Z,2023-07-02T21:02:04.000Z,,,,,,,,,,
+1337,79,mulhouse,PUBLIC_TRANSPORT,Abo,2023-07-02T19:02:04.000Z,2023-07-02T20:02:04.000Z,DEADC0DE,TEST,2023-07-02T21:02:04.000Z,DEADC0DE,TEST,2023-07-02T21:02:04.000Z,0.0,0.0,0.0,0.0
+6620,46583,city-C,PUBLIC_TRANSPORT,Titre Journée,2023-06-02T10:24:20+01:00,2023-06-03T12:55:22+01:00,,,,,,,,,,
+";
+        let rdr = Reader::from_reader(example_data.as_bytes());
         // ACT
         let result = read_csv(rdr).unwrap();
         // ASSERT
-        assert_eq!(6, result.len())
+        assert_eq!(3, result.len())
     }
 
     #[test]
@@ -174,6 +179,7 @@ mod tests {
             to_label: None,
             to_latitude: None,
             to_longitude: None,
+            validation_datetime: None,
         };
 
         // ACT
@@ -182,14 +188,14 @@ mod tests {
 
         // FIXME Binary data change between tests o
         assert!(!result.to_string().is_empty());
-        assert_eq!("0x7b226964223a313333372c22757365725f6964223a312c226e6574776f726b223a226d756c686f757365222c2273657276696365223a225055424c49435f5452414e53504f5254222c226c6162656c223a22424c41424c41424c41222c22637265617465645f6174223a22323032332d31312d30375431303a33353a30385a222c2266726f6d5f636f6f7264223a6e756c6c2c2266726f6d5f6c6162656c223a6e756c6c2c2266726f6d5f6461746574696d65223a6e756c6c2c2266726f6d5f6c61746974756465223a6e756c6c2c2266726f6d5f6c6f6e676974756465223a6e756c6c2c22746f5f636f6f7264223a6e756c6c2c22746f5f6c6162656c223a6e756c6c2c22746f5f6461746574696d65223a6e756c6c2c22746f5f6c61746974756465223a6e756c6c2c22746f5f6c6f6e676974756465223a6e756c6c7d",
+        assert_eq!("0x7b226964223a313333372c22757365725f6964223a312c226e6574776f726b223a226d756c686f757365222c2273657276696365223a225055424c49435f5452414e53504f5254222c226c6162656c223a22424c41424c41424c41222c22637265617465645f6174223a22323032332d31312d30375431303a33353a30385a222c2266726f6d5f636f6f7264223a6e756c6c2c2266726f6d5f6c6162656c223a6e756c6c2c2266726f6d5f6461746574696d65223a6e756c6c2c2266726f6d5f6c61746974756465223a6e756c6c2c2266726f6d5f6c6f6e676974756465223a6e756c6c2c22746f5f636f6f7264223a6e756c6c2c22746f5f6c6162656c223a6e756c6c2c22746f5f6461746574696d65223a6e756c6c2c22746f5f6c61746974756465223a6e756c6c2c22746f5f6c6f6e676974756465223a6e756c6c2c2276616c69646174696f6e5f6461746574696d65223a6e756c6c7d",
          result.to_string());
     }
 
     #[test]
     fn find_earliest_mobility_record_should_work() {
         // ARRANGE
-        let mut rdr = Reader::from_path("./data/dataset-extract.csv").unwrap();
+        let rdr = Reader::from_path("./data/dataset-extract.csv").unwrap();
         let records = read_csv(rdr).unwrap();
 
         // ACT
@@ -205,7 +211,7 @@ mod tests {
     #[test]
     fn find_latest_mobility_record_should_work() {
         // ARRANGE
-        let mut rdr = Reader::from_path("./data/dataset-extract.csv").unwrap();
+        let rdr = Reader::from_path("./data/dataset-extract.csv").unwrap();
         let records = read_csv(rdr).unwrap();
 
         // ACT
@@ -218,7 +224,19 @@ mod tests {
     #[test]
     fn create_behaviors_from_records_should_work() {
         // ARRANGE
-        let mut rdr = Reader::from_path("./data/dataset-extract.csv").unwrap();
+        let rdr = Reader::from_path("./data/dataset-extract.csv").unwrap();
+        let records = read_csv(rdr).unwrap();
+
+        // ACT
+        let behaviors = generate_behaviors_from_records(records.clone());
+        // ASSERT
+        assert_eq!(records.len(), behaviors.len());
+    }
+
+    #[test]
+    fn create_behaviors_from_sample2_should_work() {
+        // ARRANGE
+        let rdr = Reader::from_path("./data/sample-2-extract.csv").unwrap();
         let records = read_csv(rdr).unwrap();
 
         // ACT
-- 
GitLab


From 32d82444dc40ba64db679472c9235033b589b9c6 Mon Sep 17 00:00:00 2001
From: Anthony Graignic <anthony.graignic@uca.fr>
Date: Mon, 29 Jan 2024 16:04:41 +0100
Subject: [PATCH 2/2] Add examples for simulate-bx-from-csv

---
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index eeff552..79328b3 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,10 @@ Options:
 -   dataset e.g. CSV file
 -   `total_simulation_duration` in seconds (or minutes ?)
 
+Others examples from MyBus' data for 1 hour:
+`cargo run simulate-bx-from-csv ../movement-data/public-transport/MF_user_mobility_june-to-august-2023_mulhouse_dataset/anonymized_june-to-august-2023_mulhouse_dataset.csv 3600`
+`cargo run simulate-bx-from-csv ../movement-data/public-transport/MF_user_mobility_june-to-november-2023_france_dataset/anonymized_june-to-november-2023_france_dataset.csv 3600`
+
 ### Send tx from CSV
 
 To send tx from accounts that got rewarded from behaviors created from a CSV Mobility dataset, run `cargo run simulate-tx-from-csv data/dataset-extract.csv 10`
-- 
GitLab