diff --git a/openVulkanoCpp/Base/UnitFormatter.cpp b/openVulkanoCpp/Base/UnitFormatter.cpp new file mode 100644 index 0000000..55de4ee --- /dev/null +++ b/openVulkanoCpp/Base/UnitFormatter.cpp @@ -0,0 +1,67 @@ +/* +* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include "UnitFormatter.hpp" +#include +#include +#include + +namespace +{ + template static std::string formatValue(T value, int precision) + { + std::ostringstream stream; + stream << std::fixed << std::setprecision(precision) << value; + return stream.str(); + } +} + +namespace OpenVulkano +{ + UnitFormatter::UnitFormatter(bool useMetric, int precisionDigits) : metric(useMetric), precision(precisionDigits) {} + + std::string UnitFormatter::Format(units::length::meter_t distance) + { + if (metric) + { + if (distance >= units::length::kilometer_t(1)) + { + return formatValue(units::length::kilometer_t(distance).value(), precision) + " km"; + } + return formatValue(distance.value(), precision) + " m"; + } + else + { + auto distanceFeet = units::length::foot_t(distance).value(); + if (distanceFeet >= 5280.0) + { + return formatValue(units::length::mile_t(distance).value(), precision) + " mi"; + } + return formatValue(distanceFeet, precision) + " ft"; + } + } + + std::string UnitFormatter::Format(units::area::square_meter_t area) + { + if (metric) + { + if (area >= units::area::square_kilometer_t(1)) + { + return formatValue(units::area::square_kilometer_t(area).value(), precision) + " km²"; + } + return formatValue(area.value(), precision) + " m²"; + } + else + { + auto areaSquareFeet = units::area::square_foot_t(area).value(); + if (areaSquareFeet >= 27878400.0) + { + return formatValue(units::area::square_mile_t(area).value(), precision) + " mi²"; + } + return formatValue(areaSquareFeet, precision) + " ft²"; + } + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Base/UnitFormatter.hpp b/openVulkanoCpp/Base/UnitFormatter.hpp new file mode 100644 index 0000000..4d59107 --- /dev/null +++ b/openVulkanoCpp/Base/UnitFormatter.hpp @@ -0,0 +1,23 @@ +/* +* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ +#pragma once + +#include +#include + +namespace OpenVulkano +{ + class UnitFormatter + { + bool metric = true; + int precision = 3; + + public: + UnitFormatter(bool useMetric = true, int precisionDigits = 3); + std::string Format(units::length::meter_t distance); + std::string Format(units::area::square_meter_t area); + }; +} \ No newline at end of file diff --git a/tests/UnitFormatter.cpp b/tests/UnitFormatter.cpp new file mode 100644 index 0000000..b7f9416 --- /dev/null +++ b/tests/UnitFormatter.cpp @@ -0,0 +1,33 @@ +/* +* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include + +#include "Base/UnitFormatter.hpp" + +using namespace units::literals; + +TEST_CASE("testUnitFormatter", "[UnitFormatter]") +{ + OpenVulkano::UnitFormatter metricFormatter(true, 2); + OpenVulkano::UnitFormatter imperialFormatter(false, 2); + + units::length::meter_t positiveDistance = 1500.0_m; + units::length::meter_t smallDistance = 0.5_m; + units::length::meter_t negativeDistance = -100.0_m; + units::area::square_meter_t smallArea(0.005); + units::area::square_meter_t negativeArea(-50.0); + + REQUIRE(metricFormatter.Format(positiveDistance) == "1.50 km"); + REQUIRE(metricFormatter.Format(smallDistance) == "0.50 m"); + REQUIRE(metricFormatter.Format(negativeDistance) == "-100.00 m"); + REQUIRE(metricFormatter.Format(smallArea) == "0.01 m²"); + REQUIRE(metricFormatter.Format(negativeArea) == "-50.00 m²"); + REQUIRE(imperialFormatter.Format(smallDistance) == "1.64 ft"); + REQUIRE(imperialFormatter.Format(negativeDistance) == "-328.08 ft"); + REQUIRE(imperialFormatter.Format(smallArea) == "0.05 ft²"); + REQUIRE(imperialFormatter.Format(negativeArea) == "-538.20 ft²"); +}