/** * @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> { NO_REPETITION { @Override public boolean test(List prefixes) { return prefixes.size() <= 1; } }, NO_RESTRICTION { @Override public boolean test(List 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 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; } }; }