/** * Copyright (C) 2022, 2024, 2025 Adrien Hopkins * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package sevenUnitsGUI; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; import sevenUnits.unit.LinearUnit; import sevenUnits.unit.Metric; import sevenUnits.unit.UnitPrefix; /** * A search rule that applies a certain set of prefixes to a unit. It always * includes the original unit in the output map. * * @since v0.4.0 * @since 2022-07-06 */ public final class PrefixSearchRule implements Function, Map> { /** * A rule that does not add any prefixed versions of units. * * @since v0.4.0 */ public static final PrefixSearchRule NO_PREFIXES = getUniversalRule( Set.of()); /** * A rule that gives every unit a common set of prefixes. * * @since v0.4.0 */ public static final PrefixSearchRule COMMON_PREFIXES = getCoherentOnlyRule( Set.of(Metric.MILLI, Metric.KILO)); /** * A rule that gives every unit all metric prefixes. * * @since v0.4.0 */ public static final PrefixSearchRule ALL_METRIC_PREFIXES = getCoherentOnlyRule( Metric.ALL_PREFIXES); /** * Gets a rule that applies the provided prefixes to coherent units only (as * defined by {@link LinearUnit#isCoherent}), except the kilogram * (specifically, units named "kilogram"). * * @param prefixes prefixes to apply * @return prefix rule * @since v0.4.0 * @since 2022-07-06 */ public static final PrefixSearchRule getCoherentOnlyRule( Set prefixes) { return new PrefixSearchRule(prefixes, u -> u.isCoherent() && !u.getName().equals("kilogram")); } /** * Gets a rule that applies the provided prefixes to all units. * * @param prefixes prefixes to apply * @return prefix rule * @since v0.4.0 * @since 2022-07-06 */ public static final PrefixSearchRule getUniversalRule( Set prefixes) { return new PrefixSearchRule(prefixes, u -> true); } /** * The set of prefixes that will be applied to the unit. */ private final Set prefixes; /** * Determines which units are given prefixes. */ private final Predicate prefixableUnitRule; /** * @param prefixes prefixes to add to units * @param prefixableUnitRule function that determines which units get * prefixes * @since v0.4.0 * @since 2022-07-06 */ public PrefixSearchRule(Set prefixes, Predicate prefixableUnitRule) { this.prefixes = Collections.unmodifiableSet(new HashSet<>(prefixes)); this.prefixableUnitRule = prefixableUnitRule; } @Override public Map apply(Entry t) { final Map outputUnits = new HashMap<>(); final String originalName = t.getKey(); final LinearUnit originalUnit = t.getValue(); outputUnits.put(originalName, originalUnit); if (this.prefixableUnitRule.test(originalUnit)) { for (final UnitPrefix prefix : this.prefixes) { outputUnits.put(prefix.getName() + originalName, originalUnit.withPrefix(prefix)); } } return Collections.unmodifiableMap(outputUnits); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof PrefixSearchRule)) return false; final PrefixSearchRule other = (PrefixSearchRule) obj; return Objects.equals(this.prefixableUnitRule, other.prefixableUnitRule) && Objects.equals(this.prefixes, other.prefixes); } /** * @return rule that determines which units get prefixes * @since v0.4.0 * @since 2022-07-09 */ public Predicate getPrefixableUnitRule() { return this.prefixableUnitRule; } /** * @return the prefixes that are applied by this rule * @since v0.4.0 * @since 2022-07-06 */ public Set getPrefixes() { return this.prefixes; } @Override public int hashCode() { return Objects.hash(this.prefixableUnitRule, this.prefixes); } @Override public String toString() { return "Apply the following prefixes: " + this.prefixes; } }