summaryrefslogtreecommitdiff
path: root/src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java
diff options
context:
space:
mode:
authorAdrien Hopkins <ahopk127@my.yorku.ca>2021-08-26 15:18:30 -0400
committerAdrien Hopkins <ahopk127@my.yorku.ca>2021-08-26 15:18:30 -0400
commitc4ae6887c32ee8d2e9e8853ffd12721d4db2fd3b (patch)
treeb51679f692e90292901669d2c1bccad347c25434 /src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java
parent360b4261ebb9b65dcf91a6e49c5d23784e592945 (diff)
parent54e481cdb7115b236bcddb86b785d88dcc757c39 (diff)
Merge branch '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..6b6abf0
--- /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.Metric;
+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 (!Metric.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 (!Metric.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 (Metric.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 (Metric.YOTTA.equals(prefix) || Metric.YOCTO.equals(prefix)) {
+ part = 0;
+ } else if (Metric.THOUSAND_PREFIXES.contains(prefix)) {
+ part = 1;
+ } else {
+ part = 2;
+ }
+ }
+ return true;
+ }
+ };
+}