Skip to content

Commit d71900e

Browse files
committed
UnitSystem code generation
- refactored the UnitSystem- moving the BaseUnits to BaseUnitSystem (SI derived from BaseUnitSystem), extended the unit mappings with the UnitSystemInfo class (containing both default and common/derived units) - updated the JsonTypes and created the UnitSystemInfoGenerator (TODO WRC) - updated existing UnitSystemTests that tested for equality/BaseUnits (almost all in fact) to use the BaseUnitSystem instead (as the IEquatble/BaseUnits interface was pushed down) - added several more unit-system mappings to the UnitDefinitions (Acceleration, AmountOfSubstance, Area, Energy & Length) - commented (temporary) part of the Ctor_WithValueAndSIUnitSystem_ReturnsQuantityWithSIUnitOrThrowsArgum test (testing for support SI support)
1 parent ff000d4 commit d71900e

28 files changed

+1675
-241
lines changed

CodeGen/Generators/QuantityJsonFilesParser.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed under MIT No Attribution, see LICENSE file at the root.
1+
// Licensed under MIT No Attribution, see LICENSE file at the root.
22
// Copyright 2013 Andreas Gullberg Larsen ([email protected]). Maintained at https://github.com/angularsen/UnitsNet.
33

44
using System;
@@ -86,7 +86,8 @@ private static void AddPrefixUnits(Quantity quantity)
8686
{
8787
SingularName = $"{prefix}{unit.SingularName.ToCamelCase()}", // "Kilo" + "NewtonPerMeter" => "KilonewtonPerMeter"
8888
PluralName = $"{prefix}{unit.PluralName.ToCamelCase()}", // "Kilo" + "NewtonsPerMeter" => "KilonewtonsPerMeter"
89-
BaseUnits = null, // Can we determine this somehow?
89+
BaseUnits = null, // Can we determine this somehow?,
90+
UnitSystems = unit.UnitSystems, // Unit systems mappings are inherited for prefixed units
9091
FromBaseToUnitFunc = $"({unit.FromBaseToUnitFunc}) / {prefixInfo.Factor}",
9192
FromUnitToBaseFunc = $"({unit.FromUnitToBaseFunc}) * {prefixInfo.Factor}",
9293
Localization = GetLocalizationForPrefixUnit(unit.Localization, prefixInfo)
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using System;
2+
using System.Linq;
3+
using CodeGen.Helpers;
4+
using CodeGen.JsonTypes;
5+
6+
namespace CodeGen.Generators.UnitsNetGen
7+
{
8+
internal class UnitSystemInfoGenerator : GeneratorBase
9+
{
10+
private readonly Quantity[] _quantities;
11+
private readonly string _unitSystemName;
12+
13+
public UnitSystemInfoGenerator(string unitSystemName, Quantity[] quantities)
14+
{
15+
_quantities = quantities;
16+
_unitSystemName = unitSystemName;
17+
}
18+
19+
public override string Generate()
20+
{
21+
Writer.WL(GeneratedFileHeader);
22+
Writer.WL($@"
23+
// ReSharper disable once CheckNamespace
24+
namespace UnitsNet.UnitSystems
25+
{{
26+
27+
public partial class {_unitSystemName}
28+
{{
29+
/// <summary>
30+
/// Returns the list of unit mappings for the current unit system
31+
/// </summary>
32+
/// <returns>The list of unit system infos</returns>
33+
public static UnitSystemInfo[] GetDefaultSystemUnits()
34+
{{
35+
return new UnitSystemInfo[]
36+
{{");
37+
foreach (Quantity quantity in _quantities)
38+
{
39+
UnitSystemMapping unitSystemMapping = quantity.UnitSystems.FirstOrDefault(x => x.UnitSystem == _unitSystemName);
40+
if (unitSystemMapping == null)
41+
{
42+
var firstCommonUnitIndex = Array.FindIndex(quantity.Units, x => x.UnitSystems.Contains(_unitSystemName));
43+
44+
if (firstCommonUnitIndex < 0)
45+
{
46+
Writer.WL(4, "null,"); // no mapping for current quantity
47+
}
48+
else
49+
{
50+
Writer.WL(4, $@"new UnitSystemInfo(null, new UnitInfo[]{{");
51+
Writer.WL(5, $@"{quantity.Name}.Info.UnitInfos[{firstCommonUnitIndex}],");
52+
var startingIndex = firstCommonUnitIndex + 1;
53+
while (true)
54+
{
55+
var nextIndex = Array.FindIndex(quantity.Units, startingIndex, x => x.UnitSystems.Contains(_unitSystemName));
56+
if (nextIndex < 0)
57+
{
58+
Writer.WL(5, @"}),");
59+
break;
60+
}
61+
else
62+
{
63+
Writer.WL(5, $@"{quantity.Name}.Info.UnitInfos[{nextIndex}],");
64+
startingIndex = nextIndex + 1;
65+
}
66+
}
67+
}
68+
}
69+
else
70+
{
71+
// find the unit index in the generated unit infos
72+
var defaultIndex = Array.FindIndex(quantity.Units, x => x.SingularName == unitSystemMapping.BaseUnit);
73+
74+
Writer.WL(4, $@"new UnitSystemInfo({quantity.Name}.Info.UnitInfos[{defaultIndex}], new UnitInfo[]{{");
75+
var startingIndex = 0;
76+
while(true)
77+
{
78+
var nextIndex = Array.FindIndex(quantity.Units, startingIndex, x => x.UnitSystems.Contains(_unitSystemName));
79+
if (nextIndex < 0)
80+
{
81+
Writer.WL(5, @"}),");
82+
break;
83+
}
84+
else
85+
{
86+
Writer.WL(5, $@"{quantity.Name}.Info.UnitInfos[{nextIndex}],");
87+
startingIndex = nextIndex + 1;
88+
}
89+
}
90+
}
91+
}
92+
93+
Writer.WL(@"
94+
};
95+
}
96+
}
97+
}
98+
");
99+
100+
return Writer.ToString();
101+
}
102+
}
103+
}

CodeGen/Generators/UnitsNetGenerator.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed under MIT No Attribution, see LICENSE file at the root.
1+
// Licensed under MIT No Attribution, see LICENSE file at the root.
22
// Copyright 2013 Andreas Gullberg Larsen ([email protected]). Maintained at https://github.com/angularsen/UnitsNet.
33

44
using System.IO;
@@ -42,6 +42,7 @@ public static void Generate(string rootDir, Quantity[] quantities)
4242
// Ensure output directories exist
4343
Directory.CreateDirectory($"{outputDir}/Quantities");
4444
Directory.CreateDirectory($"{outputDir}/Units");
45+
Directory.CreateDirectory($"{outputDir}/UnitSystems");
4546
Directory.CreateDirectory($"{testProjectDir}/GeneratedCode");
4647

4748
foreach (var quantity in quantities)
@@ -54,6 +55,12 @@ public static void Generate(string rootDir, Quantity[] quantities)
5455
Log.Information(sb.ToString());
5556
}
5657

58+
var unitSystems = quantities.SelectMany(x => x.Units.SelectMany(u=> u.UnitSystems)).Distinct();
59+
foreach (string unitSystem in unitSystems)
60+
{
61+
GenerateUnitSystemMappings(unitSystem, quantities, $"{outputDir}/UnitSystems/{unitSystem}.g.cs");
62+
}
63+
5764
GenerateIQuantityTests(quantities, $"{testProjectDir}/GeneratedCode/IQuantityTests.g.cs");
5865

5966
Log.Information("");
@@ -136,5 +143,12 @@ private static void GenerateUnitConverter(Quantity[] quantities, string filePath
136143
File.WriteAllText(filePath, content, Encoding.UTF8);
137144
Log.Information("UnitConverter.g.cs: ".PadRight(AlignPad) + "(OK)");
138145
}
146+
147+
private static void GenerateUnitSystemMappings(string unitSystemName, Quantity[] quantities, string filePath)
148+
{
149+
var content = new UnitSystemInfoGenerator(unitSystemName, quantities).Generate();
150+
File.WriteAllText(filePath, content, Encoding.UTF8);
151+
Log.Information($"{unitSystemName}.g.cs: ".PadRight(AlignPad) + "(OK)");
152+
}
139153
}
140154
}

CodeGen/JsonTypes/Quantity.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed under MIT No Attribution, see LICENSE file at the root.
1+
// Licensed under MIT No Attribution, see LICENSE file at the root.
22
// Copyright 2013 Andreas Gullberg Larsen ([email protected]). Maintained at https://github.com/angularsen/UnitsNet.
33

44
using System;
@@ -19,6 +19,7 @@ internal class Quantity
1919
public int LogarithmicScalingFactor = 1;
2020
public string Name;
2121
public Unit[] Units = Array.Empty<Unit>();
22+
public UnitSystemMapping[] UnitSystems = Array.Empty<UnitSystemMapping>();
2223
public string XmlDocRemarks;
2324
public string XmlDoc; // TODO Rename to XmlDocSummary
2425
public string ObsoleteText;

CodeGen/JsonTypes/Unit.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed under MIT No Attribution, see LICENSE file at the root.
1+
// Licensed under MIT No Attribution, see LICENSE file at the root.
22
// Copyright 2013 Andreas Gullberg Larsen ([email protected]). Maintained at https://github.com/angularsen/UnitsNet.
33

44
using System;
@@ -16,6 +16,7 @@ internal class Unit
1616
public Localization[] Localization = Array.Empty<Localization>();
1717
public string PluralName;
1818
public Prefix[] Prefixes = Array.Empty<Prefix>();
19+
public string[] UnitSystems = Array.Empty<string>();
1920
public string SingularName;
2021
public string XmlDocRemarks;
2122
public string XmlDocSummary;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace CodeGen.JsonTypes
6+
{
7+
internal class UnitSystemMapping
8+
{
9+
10+
// 0649 Field is never assigned to
11+
#pragma warning disable 0649
12+
public string UnitSystem;
13+
public string BaseUnit;
14+
15+
// 0649 Field is never assigned to
16+
#pragma warning restore 0649
17+
}
18+
}

Common/UnitDefinitions/Acceleration.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
},
1717
"FromUnitToBaseFunc": "x",
1818
"FromBaseToUnitFunc": "x",
19+
"UnitSystems": [ "SI", "CGS" ],
1920
"Prefixes": [ "Nano", "Micro", "Milli", "Centi", "Deci", "Kilo" ],
2021
"Localization": [
2122
{
@@ -33,6 +34,7 @@
3334
},
3435
"FromUnitToBaseFunc": "x*0.0254",
3536
"FromBaseToUnitFunc": "x/0.0254",
37+
"UnitSystems": [ "EE", "BI", "USC" ],
3638
"Localization": [
3739
{
3840
"Culture": "en-US",
@@ -49,6 +51,7 @@
4951
},
5052
"FromUnitToBaseFunc": "x*0.304800",
5153
"FromBaseToUnitFunc": "x/0.304800",
54+
"UnitSystems": [ "EE", "BI", "USC" ],
5255
"Localization": [
5356
{
5457
"Culture": "en-US",
@@ -120,5 +123,19 @@
120123
}
121124
]
122125
}
126+
],
127+
"UnitSystems": [
128+
{
129+
"UnitSystem": "SI",
130+
"BaseUnit": "MeterPerSecondSquared"
131+
},
132+
{
133+
"UnitSystem": "CGS",
134+
"BaseUnit": "CentimeterPerSecondSquared"
135+
},
136+
{
137+
"UnitSystem": "EE",
138+
"BaseUnit": "FootPerSecondSquared"
139+
}
123140
]
124141
}

Common/UnitDefinitions/AmountOfSubstance.json

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"BaseUnits": {
1515
"N": "Mole"
1616
},
17-
"Prefixes": [ "Nano", "Micro", "Milli", "Centi", "Deci", "Kilo", "Mega"],
17+
"UnitSystems": [ "SI", "CGS" ],
18+
"Prefixes": [ "Nano", "Micro", "Milli", "Centi", "Deci", "Kilo", "Mega" ],
1819
"Localization": [
1920
{
2021
"Culture": "en-US",
@@ -30,6 +31,7 @@
3031
},
3132
"FromUnitToBaseFunc": "x*453.59237",
3233
"FromBaseToUnitFunc": "x/453.59237",
34+
"UnitSystems": [ "BI", "USC" ],
3335
"Prefixes": [ "Nano", "Micro", "Milli", "Centi", "Deci", "Kilo" ],
3436
"Localization": [
3537
{
@@ -38,5 +40,23 @@
3840
}
3941
]
4042
}
43+
],
44+
"UnitSystems": [
45+
{
46+
"UnitSystem": "SI",
47+
"BaseUnit": "Mole"
48+
},
49+
{
50+
"UnitSystem": "CGS",
51+
"BaseUnit": "Mole"
52+
},
53+
{
54+
"UnitSystem": "BI",
55+
"BaseUnit": "PoundMole"
56+
},
57+
{
58+
"UnitSystem": "USC",
59+
"BaseUnit": "PoundMole"
60+
}
4161
]
4262
}

0 commit comments

Comments
 (0)