Skip to content

Commit

Permalink
Rewrite ConvertInput (#11449)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykhailopylyp committed Jun 3, 2021
1 parent 152873c commit 774a2fa
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,6 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter.UnitTest
[TestFixture]
public class UnitHandlerTests
{
[TestCase(new string[] { "1", "meter", "in", "centimeter" }, UnitsNet.QuantityType.Length, UnitHandler.Abbreviated.Neither)]
[TestCase(new string[] { "1", "m", "in", "cm" }, UnitsNet.QuantityType.Length, UnitHandler.Abbreviated.Both)]
[TestCase(new string[] { "1", "m", "in", "centimeter" }, UnitsNet.QuantityType.Length, UnitHandler.Abbreviated.First)]
[TestCase(new string[] { "1", "meter", "in", "cm" }, UnitsNet.QuantityType.Length, UnitHandler.Abbreviated.Second)]
public void ParsesInputForAbbreviations(string[] input, UnitsNet.QuantityType qType, UnitHandler.Abbreviated expectedResult)
{
(UnitHandler.Abbreviated abbreviated, UnitsNet.QuantityInfo quantityInfo) result = UnitHandler.ParseInputForAbbreviation(input, qType);
Assert.AreEqual(expectedResult, result.abbreviated);
}

[TestCase(new string[] { "1", "meter", "in", "centimeter" }, UnitsNet.QuantityType.Length, 100d)]
[TestCase(new string[] { "1", "DegreeCelsius", "in", "DegreeFahrenheit" }, UnitsNet.QuantityType.Temperature, 33.79999999999999d)]
public void ConvertsInput(string[] input, UnitsNet.QuantityType unit, double expectedResult)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,108 +6,45 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter
{
public static class UnitHandler
{
public enum Abbreviated
{
First,
Second,
Both,
Neither,
NotFound,
}

/// <summary>
/// Given user unit input, converts it. (E.g "1 foot in cm").
/// Given string representation of unit, converts it to the enum.
/// </summary>
/// <returns>The converted value as a double.</returns>
public static double ConvertInput(string[] split, QuantityType quantityType, CultureInfo currentCulture)
/// <returns>Corresponding enum or null.</returns>
private static Enum GetUnitEnum(string unit, QuantityInfo unitInfo)
{
string input_first_unit = split[1];
string input_second_unit = split[3];

(Abbreviated abbreviated, QuantityInfo unitInfo) = ParseInputForAbbreviation(split, quantityType);

switch (abbreviated)
UnitInfo first = Array.Find(unitInfo.UnitInfos, info => info.Name.ToLower() == unit.ToLower());
if (first != null)
{
case Abbreviated.Both:
return UnitsNet.UnitConverter.ConvertByAbbreviation(double.Parse(split[0], currentCulture), unitInfo.Name, input_first_unit, input_second_unit);

case Abbreviated.Neither:
return UnitsNet.UnitConverter.ConvertByName(double.Parse(split[0], currentCulture), unitInfo.Name, input_first_unit, input_second_unit);

case Abbreviated.Second:
UnitInfo first = Array.Find(unitInfo.UnitInfos, info => info.Name.ToLower() == input_first_unit.ToLower());
UnitParser.Default.TryParse(split[3], unitInfo.UnitType, out Enum second_unit);
return UnitsNet.UnitConverter.Convert(double.Parse(split[0], currentCulture), first.Value, second_unit);

case Abbreviated.First:
UnitParser.Default.TryParse(split[1], unitInfo.UnitType, out Enum first_unit);
UnitInfo second = Array.Find(unitInfo.UnitInfos, info => info.Name.ToLower() == input_second_unit.ToLower());
return UnitsNet.UnitConverter.Convert(double.Parse(split[0], currentCulture), first_unit, second.Value);
return first.Value;
}

case Abbreviated.NotFound:
default:
return double.NaN;
if (UnitParser.Default.TryParse(unit, unitInfo.UnitType, out Enum enum_unit))
{
return enum_unit;
}

return null;
}

/// <summary>
/// Given a split array of user input, parses the input for abbreviations (e.g. "1 cm in meters").
/// Given user unit input, converts it. (E.g "1 foot in cm").
/// </summary>
/// <returns>A tuple consisting of an Abbreviated enum and QuantityInfo.</returns>
public static (Abbreviated Abbreviated, QuantityInfo UnitInfo) ParseInputForAbbreviation(string[] split, QuantityType quantityType)
/// <returns>The converted value as a double.</returns>
public static double ConvertInput(string[] split, QuantityType quantityType, CultureInfo currentCulture)
{
string input_first_unit = split[1];
string input_second_unit = split[3];

QuantityInfo unit_info = Quantity.GetInfo(quantityType);
bool first_unit_is_abbreviated = UnitParser.Default.TryParse(split[1], unit_info.UnitType, out Enum _);
bool second_unit_is_abbreviated = UnitParser.Default.TryParse(split[3], unit_info.UnitType, out Enum _);

// 3 types of matches:
// a) 10 ft in cm (double abbreviation)
// b) 10 feet in centimeter (double unabbreviated)
// c) 10 feet in cm (single abbreviation)
string firstUnitString = split[1];
string secondUnitString = split[3];
QuantityInfo unitInfo = Quantity.GetInfo(quantityType);

if (first_unit_is_abbreviated && second_unit_is_abbreviated)
{
// a
return (Abbreviated.Both, unit_info);
}
else if ((!first_unit_is_abbreviated) && (!second_unit_is_abbreviated))
{
// b
bool first_unabbreviated = Array.Exists(unit_info.UnitInfos, unitName => unitName.Name.ToLower() == input_first_unit.ToLower());
bool second_unabbreviated = Array.Exists(unit_info.UnitInfos, unitName => unitName.Name.ToLower() == input_second_unit.ToLower());
var firstUnit = GetUnitEnum(firstUnitString, unitInfo);
var secondUnit = GetUnitEnum(secondUnitString, unitInfo);

if (first_unabbreviated && second_unabbreviated)
{
return (Abbreviated.Neither, unit_info);
}
}
else if ((first_unit_is_abbreviated && !second_unit_is_abbreviated) || (!first_unit_is_abbreviated && second_unit_is_abbreviated))
if (firstUnit != null && secondUnit != null)
{
// c
if (first_unit_is_abbreviated)
{
bool second_unabbreviated = Array.Exists(unit_info.UnitInfos, unitName => unitName.Name.ToLower() == input_second_unit.ToLower());

if (second_unabbreviated)
{
return (Abbreviated.First, unit_info);
}
}
else if (second_unit_is_abbreviated)
{
bool first_unabbreviated = Array.Exists(unit_info.UnitInfos, unitName => unitName.Name.ToLower() == input_first_unit.ToLower());

if (first_unabbreviated)
{
return (Abbreviated.Second, unit_info);
}
}
return UnitsNet.UnitConverter.Convert(double.Parse(split[0], currentCulture), firstUnit, secondUnit);
}

return (Abbreviated.NotFound, null);
return double.NaN;
}
}
}

0 comments on commit 774a2fa

Please sign in to comment.