@@ -32,7 +32,7 @@ use crate::{Hoc, HocCo2eIntensityThroughput, ShipmentFootprint, Toc};
32
32
}
33
33
} */
34
34
35
- pub struct PACTMappedFields {
35
+ pub struct PactMappedFields {
36
36
product_id_type : & ' static str ,
37
37
data_schema_id : & ' static str ,
38
38
id : String ,
@@ -42,9 +42,9 @@ pub struct PACTMappedFields {
42
42
p_cf_excluding_biogenic : Decimal ,
43
43
}
44
44
45
- impl From < & ShipmentFootprint > for PACTMappedFields {
45
+ impl From < & ShipmentFootprint > for PactMappedFields {
46
46
fn from ( shipment : & ShipmentFootprint ) -> Self {
47
- PACTMappedFields {
47
+ PactMappedFields {
48
48
product_id_type : "shipment" ,
49
49
data_schema_id : "shipment-footprint" ,
50
50
id : shipment. shipment_id . clone ( ) ,
@@ -54,7 +54,7 @@ impl From<&ShipmentFootprint> for PACTMappedFields {
54
54
. tces
55
55
. 0
56
56
. iter ( )
57
- . fold ( Decimal :: from ( 0 ) , |acc, tce| acc + tce. co2e_wtw . 0 ) ,
57
+ . fold ( Decimal :: from ( 0 ) , |acc, tce| acc + tce. transport_activity . 0 ) ,
58
58
p_cf_excluding_biogenic : shipment
59
59
. tces
60
60
. 0
@@ -64,9 +64,9 @@ impl From<&ShipmentFootprint> for PACTMappedFields {
64
64
}
65
65
}
66
66
67
- impl From < & Hoc > for PACTMappedFields {
67
+ impl From < & Hoc > for PactMappedFields {
68
68
fn from ( hoc : & Hoc ) -> Self {
69
- PACTMappedFields {
69
+ PactMappedFields {
70
70
product_id_type : "hoc" ,
71
71
data_schema_id : "hoc" ,
72
72
id : hoc. hoc_id . clone ( ) ,
@@ -83,9 +83,9 @@ impl From<&Hoc> for PACTMappedFields {
83
83
}
84
84
}
85
85
86
- impl From < & Toc > for PACTMappedFields {
86
+ impl From < & Toc > for PactMappedFields {
87
87
fn from ( toc : & Toc ) -> Self {
88
- PACTMappedFields {
88
+ PactMappedFields {
89
89
product_id_type : "toc" ,
90
90
data_schema_id : "toc" ,
91
91
id : toc. toc_id . clone ( ) ,
@@ -98,7 +98,7 @@ impl From<&Toc> for PACTMappedFields {
98
98
}
99
99
100
100
/**
101
- * converts an iLEAP type into a PACT Data Model's ProductFootprint.
101
+ * Converts an iLEAP type into a PACT Data Model's ProductFootprint.
102
102
*
103
103
* To do so, additional propertiers are needed:
104
104
* - company_name: the name of the company that is responsible for the product
@@ -114,19 +114,20 @@ pub fn to_pcf<T>(
114
114
) -> ProductFootprint
115
115
where
116
116
T : Serialize ,
117
- PACTMappedFields : for < ' a > From < & ' a T > ,
117
+ PactMappedFields : for < ' a > From < & ' a T > ,
118
118
{
119
- // massage the optional IPCC characterization factors into a tuple of the actual factors and the IPCC Characterization Factor sources
119
+ // Massage the optional IPCC characterization factors into a tuple of the actual factors and the
120
+ // IPCC Characterization Factor sources
120
121
let ( characterization_factors, characterization_factors_sources) =
121
122
to_char_factors ( characterization_factors) ;
122
123
123
- // extract the properties necessary to turn the iLEAP type into a ProductFootprint
124
+ // Extract the properties necessary to turn the iLEAP type into a ProductFootprint.
124
125
// Note: this conversion at this point is "static" and does not require any additional data.
125
126
// However, the current implementation requires the HOC data type to declare its throughput
126
127
// in tonnes (i.e. /not/ in `TEU`) – otherwise the current implementation goes nuclear.
127
128
// We are investingating whether the iLEAP Data model needs to be updated for the `TEU` unit case.
128
129
// This function will be updated as we move along.
129
- let PACTMappedFields {
130
+ let PactMappedFields {
130
131
product_id_type,
131
132
data_schema_id,
132
133
id,
@@ -136,7 +137,7 @@ where
136
137
p_cf_excluding_biogenic,
137
138
} = ileap_type. into ( ) ;
138
139
139
- // fasten your seatbelts, we are about to create a ProductFootprint...
140
+ // Fasten your seatbelts, we are about to create a ProductFootprint...
140
141
ProductFootprint {
141
142
id : PfId ( Uuid :: new_v4 ( ) ) ,
142
143
spec_version : SpecVersionString ( "2.2.0" . to_string ( ) ) ,
@@ -251,3 +252,206 @@ fn to_char_factors(
251
252
} ;
252
253
( characterization_factors, characterization_factors_sources)
253
254
}
255
+
256
+ #[ test]
257
+ fn ship_foot_to_pfc ( ) {
258
+ use crate :: { GlecDistance , Tce } ;
259
+ use rust_decimal_macros:: dec;
260
+
261
+ let ship_foot = ShipmentFootprint {
262
+ shipment_id : "shipment-test" . to_string ( ) ,
263
+ tces : vec ! [
264
+ Tce {
265
+ tce_id: "tce-1-toc-rail-1" . to_string( ) ,
266
+ prev_tce_ids: Some ( vec![ ] ) ,
267
+ toc_id: Some ( "toc-rail-1" . to_string( ) ) ,
268
+ hoc_id: None ,
269
+ shipment_id: "shipment-test" . to_string( ) ,
270
+ mass: dec!( 40000 ) . into( ) ,
271
+ distance: GlecDistance :: Actual ( dec!( 423 ) . into( ) ) ,
272
+ transport_activity: dec!( 16920 ) . into( ) ,
273
+ co2e_wtw: dec!( 118.44 ) . into( ) ,
274
+ co2e_ttw: dec!( 0 ) . into( ) ,
275
+ consignment_id: None ,
276
+ packaging_or_tr_eq_type: None ,
277
+ packaging_or_tr_eq_amount: None ,
278
+ origin: None ,
279
+ destination: None ,
280
+ departure_at: None ,
281
+ arrival_at: None ,
282
+ flight_no: None ,
283
+ voyage_no: None ,
284
+ incoterms: None ,
285
+ nox_ttw: None ,
286
+ sox_ttw: None ,
287
+ ch4_ttw: None ,
288
+ pm_ttw: None ,
289
+ } ,
290
+ Tce {
291
+ tce_id: "tce-2-hoc-transshipment-1" . to_string( ) ,
292
+ prev_tce_ids: Some ( vec![ "tce-1-toc-rail-1" . to_string( ) ] ) ,
293
+ toc_id: None ,
294
+ hoc_id: Some ( "hoc-transshipment-1" . to_string( ) ) ,
295
+ shipment_id: "shipment-test" . to_string( ) ,
296
+ mass: dec!( 40000 ) . into( ) ,
297
+ distance: GlecDistance :: Actual ( dec!( 0 ) . into( ) ) ,
298
+ transport_activity: dec!( 0 ) . into( ) ,
299
+ co2e_wtw: dec!( 1320 ) . into( ) ,
300
+ co2e_ttw: dec!( 400 ) . into( ) ,
301
+ consignment_id: None ,
302
+ packaging_or_tr_eq_type: None ,
303
+ packaging_or_tr_eq_amount: None ,
304
+ origin: None ,
305
+ destination: None ,
306
+ departure_at: None ,
307
+ arrival_at: None ,
308
+ flight_no: None ,
309
+ voyage_no: None ,
310
+ incoterms: None ,
311
+ nox_ttw: None ,
312
+ sox_ttw: None ,
313
+ ch4_ttw: None ,
314
+ pm_ttw: None ,
315
+ } ,
316
+ Tce {
317
+ tce_id: "tce-3-toc-road-1" . to_string( ) ,
318
+ prev_tce_ids: Some ( vec![ "tce-2-hoc-transshipment-1" . to_string( ) ] ) ,
319
+ toc_id: Some ( "toc-road-1" . to_string( ) ) ,
320
+ hoc_id: None ,
321
+ shipment_id: "shipment-test" . to_string( ) ,
322
+ mass: dec!( 40000 ) . into( ) ,
323
+ distance: GlecDistance :: Actual ( dec!( 423 ) . into( ) ) ,
324
+ transport_activity: dec!( 16920 ) . into( ) ,
325
+ co2e_wtw: dec!( 1692.62 ) . into( ) ,
326
+ co2e_ttw: dec!( 1505.88 ) . into( ) ,
327
+ consignment_id: None ,
328
+ packaging_or_tr_eq_type: None ,
329
+ packaging_or_tr_eq_amount: None ,
330
+ origin: None ,
331
+ destination: None ,
332
+ departure_at: None ,
333
+ arrival_at: None ,
334
+ flight_no: None ,
335
+ voyage_no: None ,
336
+ incoterms: None ,
337
+ nox_ttw: None ,
338
+ sox_ttw: None ,
339
+ ch4_ttw: None ,
340
+ pm_ttw: None ,
341
+ } ,
342
+ ]
343
+ . into ( ) ,
344
+ mass : "40000" . to_string ( ) ,
345
+ volume : None ,
346
+ number_of_items : None ,
347
+ type_of_items : None ,
348
+ } ;
349
+
350
+ let pfc = to_pcf ( & ship_foot, "test" , "urn:test" , None ) ;
351
+
352
+ assert_eq ! (
353
+ pfc. product_name_company. 0 ,
354
+ "ShipmentFootprint with id shipment-test"
355
+ ) ;
356
+ assert_eq ! ( pfc. pcf. declared_unit, DeclaredUnit :: TonKilometer ) ;
357
+ assert_eq ! ( pfc. pcf. unitary_product_amount. 0 , dec!( 33840 ) . into( ) ) ;
358
+ assert_eq ! ( pfc. pcf. p_cf_excluding_biogenic. 0 , dec!( 3131.06 ) . into( ) ) ;
359
+ }
360
+
361
+ #[ test]
362
+ fn toc_to_pcf ( ) {
363
+ use crate :: {
364
+ EnergyCarrier , EnergyCarrierType , Feedstock , FeedstockType , TemperatureControl , Toc ,
365
+ TocCo2eIntensityThroughput , TransportMode ,
366
+ } ;
367
+ use rust_decimal_macros:: dec;
368
+
369
+ let toc = Toc {
370
+ toc_id : "toc-test" . to_string ( ) ,
371
+ mode : TransportMode :: Rail ,
372
+ load_factor : Some ( dec ! ( 0.6 ) . to_string ( ) ) ,
373
+ empty_distance_factor : Some ( dec ! ( 0.33 ) . to_string ( ) ) ,
374
+ temperature_control : Some ( TemperatureControl :: Ambient ) ,
375
+ truck_loading_sequence : None ,
376
+ energy_carriers : vec ! [ EnergyCarrier {
377
+ energy_carrier: EnergyCarrierType :: Electric ,
378
+ feedstocks: Some ( vec![ Feedstock {
379
+ feedstock: FeedstockType :: Grid ,
380
+ feedstock_percentage: None ,
381
+ region_provenance: Some ( "Europe" . to_string( ) ) ,
382
+ } ] ) ,
383
+ energy_consumption: None ,
384
+ energy_consumption_unit: Some ( "MJ" . to_string( ) ) ,
385
+ emission_factor_wtw: dec!( 97 ) . into( ) ,
386
+ emission_factor_ttw: dec!( 0 ) . into( ) ,
387
+ } ]
388
+ . into ( ) ,
389
+ co2e_intensity_wtw : dec ! ( 0.007 ) . into ( ) ,
390
+ co2e_intensity_ttw : dec ! ( 0 ) . into ( ) ,
391
+ co2e_intensity_throughput : TocCo2eIntensityThroughput :: Tkm ,
392
+ is_verified : true ,
393
+ is_accredited : true ,
394
+ description : None ,
395
+ air_shipping_option : None ,
396
+ flight_length : None ,
397
+ glec_data_quality_index : None ,
398
+ } ;
399
+
400
+ let pfc = to_pcf ( & toc, "test" , "urn:test" , None ) ;
401
+
402
+ assert_eq ! ( pfc. product_name_company. 0 , "TOC with ID toc-test" ) ;
403
+ assert_eq ! ( pfc. pcf. declared_unit, DeclaredUnit :: TonKilometer ) ;
404
+ assert_eq ! ( pfc. pcf. unitary_product_amount. 0 , dec!( 1 ) . into( ) ) ;
405
+ assert_eq ! ( pfc. pcf. p_cf_excluding_biogenic. 0 , dec!( 0.007 ) . into( ) ) ;
406
+ }
407
+
408
+ #[ test]
409
+ fn hoc_to_pfc ( ) {
410
+ use crate :: {
411
+ EnergyCarrier , EnergyCarrierType , Hoc , HubType , TemperatureControl , TransportMode ,
412
+ } ;
413
+ use rust_decimal_macros:: dec;
414
+
415
+ let hoc = Hoc {
416
+ hoc_id : "hoc-test" . to_string ( ) ,
417
+ hub_type : HubType :: Transshipment ,
418
+ temperature_control : Some ( TemperatureControl :: Refrigerated ) ,
419
+ inbound_transport_mode : Some ( TransportMode :: Road ) ,
420
+ outbound_transport_mode : Some ( TransportMode :: Rail ) ,
421
+ is_verified : true ,
422
+ is_accredited : true ,
423
+ hub_location : None ,
424
+ packaging_or_tr_eq_type : None ,
425
+ packaging_or_tr_eq_amount : None ,
426
+ description : None ,
427
+ energy_carriers : vec ! [
428
+ EnergyCarrier {
429
+ energy_carrier: EnergyCarrierType :: Diesel ,
430
+ feedstocks: None ,
431
+ energy_consumption: None ,
432
+ energy_consumption_unit: Some ( "kg" . to_string( ) ) ,
433
+ emission_factor_wtw: dec!( 4.13 ) . into( ) ,
434
+ emission_factor_ttw: dec!( 3.17 ) . into( ) ,
435
+ } ,
436
+ EnergyCarrier {
437
+ energy_carrier: EnergyCarrierType :: Electric ,
438
+ feedstocks: None ,
439
+ energy_consumption: None ,
440
+ energy_consumption_unit: Some ( "MJ" . to_string( ) ) ,
441
+ emission_factor_wtw: dec!( 97 ) . into( ) ,
442
+ emission_factor_ttw: dec!( 0 ) . into( ) ,
443
+ } ,
444
+ ]
445
+ . into ( ) ,
446
+ co2e_intensity_wtw : dec ! ( 33 ) . into ( ) ,
447
+ co2e_intensity_ttw : dec ! ( 10 ) . into ( ) ,
448
+ co2e_intensity_throughput : HocCo2eIntensityThroughput :: Tonnes ,
449
+ } ;
450
+
451
+ let pfc = to_pcf ( & hoc, "test" , "urn:test" , None ) ;
452
+
453
+ assert_eq ! ( pfc. product_name_company. 0 , "HOC with ID hoc-test" ) ;
454
+ assert_eq ! ( pfc. pcf. declared_unit, DeclaredUnit :: Kilogram ) ;
455
+ assert_eq ! ( pfc. pcf. unitary_product_amount. 0 , dec!( 1000 ) . into( ) ) ;
456
+ assert_eq ! ( pfc. pcf. p_cf_excluding_biogenic. 0 , dec!( 33 ) . into( ) ) ;
457
+ }
0 commit comments