2021-08-11 17:22:30 +02:00
|
|
|
|
// Copyright (c) Microsoft Corporation
|
|
|
|
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
|
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
2021-06-09 10:46:19 +01:00
|
|
|
|
using System.Collections.Generic;
|
2024-09-16 16:09:43 -04:00
|
|
|
|
|
2021-06-09 10:46:19 +01:00
|
|
|
|
using UnitsNet;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Community.PowerToys.Run.Plugin.UnitConverter
|
|
|
|
|
|
{
|
|
|
|
|
|
public static class UnitHandler
|
|
|
|
|
|
{
|
2024-09-25 14:59:49 +02:00
|
|
|
|
private static readonly int _roundingSignificantDigits = 4;
|
2021-06-09 10:46:19 +01:00
|
|
|
|
|
2022-08-24 11:50:34 +02:00
|
|
|
|
private static readonly QuantityInfo[] _included = new QuantityInfo[]
|
2021-06-09 10:46:19 +01:00
|
|
|
|
{
|
2022-08-24 11:50:34 +02:00
|
|
|
|
Acceleration.Info,
|
|
|
|
|
|
Angle.Info,
|
|
|
|
|
|
Area.Info,
|
|
|
|
|
|
Duration.Info,
|
|
|
|
|
|
Energy.Info,
|
|
|
|
|
|
Information.Info,
|
|
|
|
|
|
Length.Info,
|
|
|
|
|
|
Mass.Info,
|
|
|
|
|
|
Power.Info,
|
|
|
|
|
|
Pressure.Info,
|
|
|
|
|
|
Speed.Info,
|
|
|
|
|
|
Temperature.Info,
|
|
|
|
|
|
Volume.Info,
|
2021-06-09 10:46:19 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Given string representation of unit, converts it to the enum.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>Corresponding enum or null.</returns>
|
|
|
|
|
|
private static Enum GetUnitEnum(string unit, QuantityInfo unitInfo)
|
|
|
|
|
|
{
|
2022-08-24 11:50:34 +02:00
|
|
|
|
UnitInfo first = Array.Find(unitInfo.UnitInfos, info =>
|
2023-12-28 13:37:13 +03:00
|
|
|
|
string.Equals(unit, info.Name, StringComparison.OrdinalIgnoreCase) ||
|
|
|
|
|
|
string.Equals(unit, info.PluralName, StringComparison.OrdinalIgnoreCase));
|
2022-08-24 11:50:34 +02:00
|
|
|
|
|
2021-06-09 10:46:19 +01:00
|
|
|
|
if (first != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return first.Value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-20 11:27:29 +02:00
|
|
|
|
if (UnitsNetSetup.Default.UnitParser.TryParse(unit, unitInfo.UnitType, out Enum enum_unit))
|
2021-06-09 10:46:19 +01:00
|
|
|
|
{
|
|
|
|
|
|
return enum_unit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-11-29 19:32:07 -06:00
|
|
|
|
var cultureInfoEnglish = new System.Globalization.CultureInfo("en-US");
|
2024-06-20 11:27:29 +02:00
|
|
|
|
if (UnitsNetSetup.Default.UnitParser.TryParse(unit, unitInfo.UnitType, cultureInfoEnglish, out Enum enum_unit_en))
|
2022-11-29 09:54:02 -05:00
|
|
|
|
{
|
|
|
|
|
|
return enum_unit_en;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-09 10:46:19 +01:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-04-19 12:20:12 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Rounds the value to the predefined number of significant digits.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="value">Value to be rounded</param>
|
|
|
|
|
|
public static double Round(double value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (value == 0.0D)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var power = Math.Floor(Math.Log10(Math.Abs(value)));
|
|
|
|
|
|
var exponent = Math.Pow(10, power);
|
2024-09-25 14:59:49 +02:00
|
|
|
|
var rounded = Math.Round(value / exponent, _roundingSignificantDigits) * exponent;
|
2022-04-19 12:20:12 +02:00
|
|
|
|
return rounded;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-09 10:46:19 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Given parsed ConvertModel, computes result. (E.g "1 foot in cm").
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>The converted value as a double.</returns>
|
2022-08-24 11:50:34 +02:00
|
|
|
|
public static double ConvertInput(ConvertModel convertModel, QuantityInfo quantityInfo)
|
2021-06-09 10:46:19 +01:00
|
|
|
|
{
|
2022-08-24 11:50:34 +02:00
|
|
|
|
var fromUnit = GetUnitEnum(convertModel.FromUnit, quantityInfo);
|
|
|
|
|
|
var toUnit = GetUnitEnum(convertModel.ToUnit, quantityInfo);
|
2021-06-09 10:46:19 +01:00
|
|
|
|
|
|
|
|
|
|
if (fromUnit != null && toUnit != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return UnitsNet.UnitConverter.Convert(convertModel.Value, fromUnit, toUnit);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return double.NaN;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Given ConvertModel returns collection of possible results.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>The converted value as a double.</returns>
|
|
|
|
|
|
public static IEnumerable<UnitConversionResult> Convert(ConvertModel convertModel)
|
|
|
|
|
|
{
|
|
|
|
|
|
var results = new List<UnitConversionResult>();
|
2022-08-24 11:50:34 +02:00
|
|
|
|
foreach (var quantityInfo in _included)
|
2021-06-09 10:46:19 +01:00
|
|
|
|
{
|
2022-08-24 11:50:34 +02:00
|
|
|
|
double convertedValue = UnitHandler.ConvertInput(convertModel, quantityInfo);
|
2021-06-09 10:46:19 +01:00
|
|
|
|
|
|
|
|
|
|
if (!double.IsNaN(convertedValue))
|
|
|
|
|
|
{
|
2022-08-24 11:50:34 +02:00
|
|
|
|
UnitConversionResult result = new UnitConversionResult(Round(convertedValue), convertModel.ToUnit, quantityInfo);
|
2021-06-09 10:46:19 +01:00
|
|
|
|
results.Add(result);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return results;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|