summaryrefslogtreecommitdiff
path: root/src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java
diff options
context:
space:
mode:
authorAdrien Hopkins <ahopk127@my.yorku.ca>2021-06-28 17:17:32 -0500
committerAdrien Hopkins <ahopk127@my.yorku.ca>2021-06-28 17:17:32 -0500
commit236b497f516694929b9fe409508a7cce21ca9e6e (patch)
tree14d2a49900d706070882cfe150e08ec1882cdbc2 /src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java
parenta34d79383061ba53951f3f69a44f142820e82216 (diff)
parent78af49e0e5b2ab2eaab87e62c33089c5caa834f8 (diff)
Merge branch 'new-name' into develop
Diffstat (limited to 'src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java')
-rw-r--r--src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java b/src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java
new file mode 100644
index 0000000..835651e
--- /dev/null
+++ b/src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java
@@ -0,0 +1,95 @@
+/**
+ * @since 2020-08-26
+ */
+package sevenUnits.converterGUI;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+import sevenUnits.unit.SI;
+import sevenUnits.unit.UnitPrefix;
+
+/**
+ * A rule that specifies whether prefix repetition is allowed
+ *
+ * @since 2020-08-26
+ */
+enum DefaultPrefixRepetitionRule implements Predicate<List<UnitPrefix>> {
+ NO_REPETITION {
+ @Override
+ public boolean test(List<UnitPrefix> prefixes) {
+ return prefixes.size() <= 1;
+ }
+ },
+ NO_RESTRICTION {
+ @Override
+ public boolean test(List<UnitPrefix> prefixes) {
+ return true;
+ }
+ },
+ /**
+ * You are allowed to have any number of Yotta/Yocto followed by possibly one
+ * Kilo-Zetta/Milli-Zepto followed by possibly one Deca/Hecto. Same for
+ * reducing prefixes, don't mix magnifying and reducing. Non-metric
+ * (including binary) prefixes can't be repeated.
+ */
+ COMPLEX_REPETITION {
+ @Override
+ public boolean test(List<UnitPrefix> prefixes) {
+ // determine whether we are magnifying or reducing
+ final boolean magnifying;
+ if (prefixes.isEmpty())
+ return true;
+ else if (prefixes.get(0).getMultiplier() > 1) {
+ magnifying = true;
+ } else {
+ magnifying = false;
+ }
+
+ // if the first prefix is non-metric (including binary prefixes),
+ // assume we are using non-metric prefixes
+ // non-metric prefixes are allowed, but can't be repeated.
+ if (!SI.DECIMAL_PREFIXES.contains(prefixes.get(0)))
+ return NO_REPETITION.test(prefixes);
+
+ int part = 0; // 0=yotta/yoctos, 1=kilo-zetta/milli-zepto,
+ // 2=deka,hecto,deci,centi
+
+ for (final UnitPrefix prefix : prefixes) {
+ // check that the current prefix is metric and appropriately
+ // magnifying/reducing
+ if (!SI.DECIMAL_PREFIXES.contains(prefix))
+ return false;
+ if (magnifying != prefix.getMultiplier() > 1)
+ return false;
+
+ // check if the current prefix is correct
+ // since part is set *after* this check, part designates the state
+ // of the *previous* prefix
+ switch (part) {
+ case 0:
+ // do nothing, any prefix is valid after a yotta
+ break;
+ case 1:
+ // after a kilo-zetta, only deka/hecto are valid
+ if (SI.THOUSAND_PREFIXES.contains(prefix))
+ return false;
+ break;
+ case 2:
+ // deka/hecto must be the last prefix, so this is always invalid
+ return false;
+ }
+
+ // set part
+ if (SI.YOTTA.equals(prefix) || SI.YOCTO.equals(prefix)) {
+ part = 0;
+ } else if (SI.THOUSAND_PREFIXES.contains(prefix)) {
+ part = 1;
+ } else {
+ part = 2;
+ }
+ }
+ return true;
+ }
+ };
+}