Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace f32 usage with Decimal #110

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
356 changes: 353 additions & 3 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ chrono = { version = "0.4.38", default-features = false, features = ["serde"] }
uuid = { version = "1", default-features = false, features = ["v4"] }
validator = { version = "0.18.1", default-features = false, features = ["derive"] }
regex = "1.10.6"
rust_decimal = { version = "1.36.0", features = ["serde-with-arbitrary-precision"] }

[dev-dependencies]
chrono = { version = "0.4.38", default-features = false, features = ["clock"] }
serde_json = "1"
mockall = "0.13.0"
jsonschema = "0.19"
rust_decimal_macros = "1.36.0"
7 changes: 4 additions & 3 deletions src/tests/schema_validation/v1_6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ mod tests {
};
use chrono::Utc;
use jsonschema::JSONSchema;
use rust_decimal_macros::dec;

#[test]
fn validate_authorize() {
Expand Down Expand Up @@ -502,10 +503,10 @@ mod tests {
charging_rate_unit: ChargingRateUnitType::W,
charging_schedule_period: vec![ChargingSchedulePeriod {
start_period: 0,
limit: 0.0,
limit: dec!(0.0),
number_phases: Some(1),
}],
min_charging_rate: Some(1.0),
min_charging_rate: Some(dec!(1.0)),
}),
};

Expand Down Expand Up @@ -939,7 +940,7 @@ mod tests {
charging_rate_unit: ChargingRateUnitType::W,
charging_schedule_period: vec![ChargingSchedulePeriod {
start_period: 0,
limit: 0.0,
limit: dec!(0.0),
number_phases: None,
}],
min_charging_rate: None,
Expand Down
39 changes: 20 additions & 19 deletions src/tests/schema_validation/v2_0_1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ mod tests {
use crate::v2_0_1::messages::update_firmware::{UpdateFirmwareRequest, UpdateFirmwareResponse};
use chrono::Utc;
use jsonschema::JSONSchema;
use rust_decimal_macros::dec;

#[test]
fn validate_authorize_request() {
Expand Down Expand Up @@ -780,7 +781,7 @@ mod tests {
#[test]
fn validate_cost_updated_request() {
let test = CostUpdatedRequest {
total_cost: 0.0,
total_cost: dec!(0.0),
transaction_id: "".to_string(),
};
let schema = include_str!("schemas/v2.0.1/CostUpdatedRequest.json");
Expand Down Expand Up @@ -1203,7 +1204,7 @@ mod tests {
charging_rate_unit: ChargingRateUnitEnumType::W,
charging_schedule_period: vec![ChargingSchedulePeriodType {
start_period: 0,
limit: 0.0,
limit: dec!(0.0),
number_phases: Some(1),
phase_to_use: Some(1),
}],
Expand Down Expand Up @@ -1739,7 +1740,7 @@ mod tests {
meter_value: vec![MeterValueType {
timestamp: Utc::now(),
sampled_value: vec![SampledValueType {
value: 0.0,
value: dec!(0.0),
context: Some(ReadingContextEnumType::SampleClock),
measurand: Some(MeasurandEnumType::CurrentExport),
phase: Some(PhaseEnumType::L1),
Expand Down Expand Up @@ -1799,10 +1800,10 @@ mod tests {
start_schedule: Some(Utc::now()),
duration: Some(10),
charging_rate_unit: ChargingRateUnitEnumType::W,
min_charging_rate: Some(10.0),
min_charging_rate: Some(dec!(10.0)),
charging_schedule_period: vec![ChargingSchedulePeriodType {
start_period: 0,
limit: 0.0,
limit: dec!(0.0),
number_phases: Some(0),
phase_to_use: Some(0),
}],
Expand Down Expand Up @@ -2022,10 +2023,10 @@ mod tests {
start_schedule: Some(Utc::now()),
duration: Some(0),
charging_rate_unit: ChargingRateUnitEnumType::W,
min_charging_rate: Some(0.0),
min_charging_rate: Some(dec!(0.0)),
charging_schedule_period: vec![ChargingSchedulePeriodType {
start_period: 0,
limit: 0.0,
limit: dec!(0.0),
number_phases: Some(0),
phase_to_use: Some(0),
}],
Expand Down Expand Up @@ -2170,7 +2171,7 @@ mod tests {
variable_monitoring: vec![VariableMonitoringType {
id: 0,
transaction: false,
value: 0.0,
value: dec!(0.0),
kind: MonitorEnumType::UpperThreshold,
severity: 0,
}],
Expand Down Expand Up @@ -2235,8 +2236,8 @@ mod tests {
variable_characteristics: Some(VariableCharacteristicsType {
unit: Some("unit".to_string()),
data_type: DataEnumType::String,
min_limit: Some(0.0),
max_limit: Some(0.0),
min_limit: Some(dec!(0.0)),
max_limit: Some(dec!(0.0)),
values_list: Some("values_list".to_string()),
supports_monitoring: false,
}),
Expand Down Expand Up @@ -2373,10 +2374,10 @@ mod tests {
start_schedule: Some(Utc::now()),
duration: Some(1),
charging_rate_unit: ChargingRateUnitEnumType::W,
min_charging_rate: Some(1.0),
min_charging_rate: Some(dec!(1.0)),
charging_schedule_period: vec![ChargingSchedulePeriodType {
start_period: 0,
limit: 0.0,
limit: dec!(0.0),
number_phases: Some(1),
phase_to_use: Some(4),
}],
Expand Down Expand Up @@ -2460,10 +2461,10 @@ mod tests {
start_schedule: Some(Utc::now()),
duration: Some(1),
charging_rate_unit: ChargingRateUnitEnumType::W,
min_charging_rate: Some(0.1),
min_charging_rate: Some(dec!(0.1)),
charging_schedule_period: vec![ChargingSchedulePeriodType {
start_period: 0,
limit: 0.0,
limit: dec!(0.0),
number_phases: Some(1),
phase_to_use: Some(1),
}],
Expand Down Expand Up @@ -2836,10 +2837,10 @@ mod tests {
start_schedule: Some(Utc::now()),
duration: Some(0),
charging_rate_unit: ChargingRateUnitEnumType::W,
min_charging_rate: Some(0.0),
min_charging_rate: Some(dec!(0.0)),
charging_schedule_period: vec![ChargingSchedulePeriodType {
start_period: 0,
limit: 0.0,
limit: dec!(0.0),
number_phases: Some(0),
phase_to_use: Some(0),
}],
Expand Down Expand Up @@ -3110,7 +3111,7 @@ mod tests {
set_monitoring_data: vec![SetMonitoringDataType {
id: Some(0),
transaction: Some(false),
value: 0.0,
value: dec!(0.0),
kind: MonitorEnumType::UpperThreshold,
severity: 0,
component: ComponentType {
Expand Down Expand Up @@ -3360,7 +3361,7 @@ mod tests {
meter_value: Some(vec![MeterValueType {
timestamp: Utc::now(),
sampled_value: vec![SampledValueType {
value: 0.0,
value: dec!(0.0),
context: Some(ReadingContextEnumType::InterruptionBegin),
measurand: Some(MeasurandEnumType::CurrentExport),
phase: Some(PhaseEnumType::L1),
Expand Down Expand Up @@ -3394,7 +3395,7 @@ mod tests {
#[test]
fn validate_transaction_event_response() {
let test = TransactionEventResponse {
total_cost: Some(0.0),
total_cost: Some(dec!(0.0)),
charging_priority: Some(0),
id_token_info: Some(IdTokenInfoType {
status: AuthorizationStatusEnumType::Accepted,
Expand Down
4 changes: 3 additions & 1 deletion src/v1_6/types/charging_schedule.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use chrono::{DateTime, Utc};
use rust_decimal::Decimal;

use super::{ChargingRateUnitType, ChargingSchedulePeriod};

Expand All @@ -18,5 +19,6 @@ pub struct ChargingSchedule {
pub charging_schedule_period: Vec<ChargingSchedulePeriod>,
/// Optional. Minimum charging rate supported by the electric vehicle. The unit of measure is defined by the chargingRateUnit. This parameter is intended to be used by a local smart charging algorithm to optimize the power allocation for in the case a charging process is inefficient at lower charging rates. Accepts at most one digit fraction (e.g. 8.1)
#[serde(skip_serializing_if = "Option::is_none")]
pub min_charging_rate: Option<f32>,
#[serde(with = "rust_decimal::serde::arbitrary_precision_option")]
pub min_charging_rate: Option<Decimal>,
}
5 changes: 4 additions & 1 deletion src/v1_6/types/charging_schedule_period.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use rust_decimal::Decimal;

/// Charging schedule period structure defines a time period in a charging schedule, as used in: ChargingSchedule.
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")]
pub struct ChargingSchedulePeriod {
/// Required. Start of the period, in seconds from the start of schedule. The value of StartPeriod also defines the stop time of the previous period.
pub start_period: i32,
/// Required. Charging rate limit during the schedule period, in the applicable chargingRateUnit, for example in Amperes or Watts. Accepts at most one digit fraction (e.g. 8.1).
pub limit: f32,
#[serde(with = "rust_decimal::serde::arbitrary_precision")]
pub limit: Decimal,
/// Optional. The number of phases that can be used for charging. If a number of phases is needed, numberPhases=3 will be assumed unless another number is given.
#[serde(skip_serializing_if = "Option::is_none")]
pub number_phases: Option<i32>,
Expand Down
5 changes: 4 additions & 1 deletion src/v2_0_1/datatypes/charging_schedule_period_type.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rust_decimal::Decimal;

/// Charging schedule period structure defines a time period in a charging schedule
/// ChargingSchedulePeriodType is used by: Common:ChargingScheduleType , Common:CompositeScheduleType
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Default)]
Expand All @@ -6,7 +8,8 @@ pub struct ChargingSchedulePeriodType {
/// Required. Start of the period, in seconds from the start of schedule. The value of StartPeriod also defines the stop time of the previous period.
pub start_period: i32,
/// Required. Charging rate limit during the schedule period, in the applicable chargingRateUnit, for example in Amperes (A) or Watts (W). Accepts at most one digit fraction (e.g. 8.1).
pub limit: f32,
#[serde(with = "rust_decimal::serde::arbitrary_precision")]
pub limit: Decimal,
/// Optional. The number of phases that can be used for charging. If a number of phases is needed, numberPhases=3 will be assumed unless another number is given.
#[serde(skip_serializing_if = "Option::is_none")]
pub number_phases: Option<i32>,
Expand Down
4 changes: 3 additions & 1 deletion src/v2_0_1/datatypes/charging_schedule_type.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use chrono::DateTime;
use chrono::Utc;
use rust_decimal::Decimal;
use validator::Validate;

use super::charging_schedule_period_type::ChargingSchedulePeriodType;
Expand All @@ -23,7 +24,8 @@ pub struct ChargingScheduleType {
pub charging_rate_unit: ChargingRateUnitEnumType,
/// Optional. Minimum charging rate supported by the EV. The unit of measure is defined by the chargingRateUnit. This parameter is intended to be used by a local smart charging algorithm to optimize the power allocation for in the case a charging process is inefficient at lower charging rates. Accepts at most one digit fraction (e.g. 8.1)
#[serde(skip_serializing_if = "Option::is_none")]
pub min_charging_rate: Option<f32>,
#[serde(with = "rust_decimal::serde::arbitrary_precision_option")]
pub min_charging_rate: Option<Decimal>,
/// Required. List of ChargingSchedulePeriod elements defining maximum power or current usage over time. The maximum number of periods, that is supported by the Charging Station, if less than 1024, is set by device model variable SmartChargingCtrlr.PeriodsPerSchedule
#[validate(length(min = 1))]
pub charging_schedule_period: Vec<ChargingSchedulePeriodType>,
Expand Down
5 changes: 4 additions & 1 deletion src/v2_0_1/datatypes/sampled_value_type.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rust_decimal::Decimal;

use super::signed_meter_value_type::SignedMeterValueType;
use super::unit_of_measure_type::UnitOfMeasureType;
use crate::v2_0_1::enumerations::location_enum_type::LocationEnumType;
Expand All @@ -11,7 +13,8 @@ use crate::v2_0_1::enumerations::reading_context_enum_type::ReadingContextEnumTy
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")]
pub struct SampledValueType {
pub value: f32,
#[serde(with = "rust_decimal::serde::arbitrary_precision")]
pub value: Decimal,
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<ReadingContextEnumType>,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down
5 changes: 4 additions & 1 deletion src/v2_0_1/datatypes/set_monitoring_data_type.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rust_decimal::Decimal;

use super::component_type::ComponentType;
use super::variable_type::VariableType;
use crate::v2_0_1::enumerations::monitor_enum_type::MonitorEnumType;
Expand All @@ -11,7 +13,8 @@ pub struct SetMonitoringDataType {
pub id: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction: Option<bool>,
pub value: f32,
#[serde(with = "rust_decimal::serde::arbitrary_precision")]
pub value: Decimal,
#[serde(rename = "type")]
pub kind: MonitorEnumType,
pub severity: u8,
Expand Down
8 changes: 6 additions & 2 deletions src/v2_0_1/datatypes/variable_characteristics_type.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rust_decimal::Decimal;

use crate::v2_0_1::enumerations::data_enum_type::DataEnumType;

/// Fixed read-only parameters of a variable.
Expand All @@ -9,9 +11,11 @@ pub struct VariableCharacteristicsType {
pub unit: Option<String>,
pub data_type: DataEnumType,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_limit: Option<f32>,
#[serde(with = "rust_decimal::serde::arbitrary_precision_option")]
pub min_limit: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_limit: Option<f32>,
#[serde(with = "rust_decimal::serde::arbitrary_precision_option")]
pub max_limit: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none")]
pub values_list: Option<String>,
pub supports_monitoring: bool,
Expand Down
5 changes: 4 additions & 1 deletion src/v2_0_1/datatypes/variable_monitoring_type.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rust_decimal::Decimal;

use crate::v2_0_1::enumerations::monitor_enum_type::MonitorEnumType;

/// A monitoring setting for a variable.
Expand All @@ -7,7 +9,8 @@ use crate::v2_0_1::enumerations::monitor_enum_type::MonitorEnumType;
pub struct VariableMonitoringType {
pub id: i32,
pub transaction: bool,
pub value: f32,
#[serde(with = "rust_decimal::serde::arbitrary_precision")]
pub value: Decimal,
#[serde(rename = "type")]
pub kind: MonitorEnumType,
pub severity: u8,
Expand Down
4 changes: 3 additions & 1 deletion src/v2_0_1/messages/cost_updated.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! CostUpdated
use rust_decimal::Decimal;
use validator::Validate;

/// CostUpdatedRequest, sent by the CSMS to the Charging Station.
Expand All @@ -8,7 +9,8 @@ use validator::Validate;
#[serde(rename_all = "camelCase")]
pub struct CostUpdatedRequest {
/// Current total cost, based on the information known by the CSMS, of the transaction including taxes. In the currency configured with the configuration Variable: [Currency]
pub total_cost: f32,
#[serde(with = "rust_decimal::serde::arbitrary_precision")]
pub total_cost: Decimal,
/// Transaction Id of the transaction the current cost are asked for.
#[validate(length(min = 0, max = 36))]
pub transaction_id: String,
Expand Down
4 changes: 3 additions & 1 deletion src/v2_0_1/messages/transaction_event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use chrono::DateTime;
use chrono::Utc;
use rust_decimal::Decimal;

use crate::v2_0_1::datatypes::evse_type::EVSEType;
use crate::v2_0_1::datatypes::id_token_info_type::IdTokenInfoType;
Expand Down Expand Up @@ -40,7 +41,8 @@ pub struct TransactionEventRequest {
#[serde(rename_all = "camelCase")]
pub struct TransactionEventResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub total_cost: Option<f32>,
#[serde(with = "rust_decimal::serde::arbitrary_precision_option")]
pub total_cost: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none")]
pub charging_priority: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down