001/* 002 * ============================================================================ 003 * Copyright © 2002-2023 by Thomas Thrien. 004 * All Rights Reserved. 005 * ============================================================================ 006 * Licensed to the public under the agreements of the GNU Lesser General Public 007 * License, version 3.0 (the "License"). You may obtain a copy of the License at 008 * 009 * http://www.gnu.org/licenses/lgpl.html 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017 018package org.tquadrat.foundation.value; 019 020import static java.lang.String.format; 021import static java.math.MathContext.DECIMAL128; 022import static java.util.Arrays.stream; 023import static org.apiguardian.api.API.Status.STABLE; 024import static org.tquadrat.foundation.lang.Objects.requireNotEmptyArgument; 025import static org.tquadrat.foundation.value.Length.FOOT; 026import static org.tquadrat.foundation.value.Length.KILOMETER; 027import static org.tquadrat.foundation.value.Length.MILE; 028import static org.tquadrat.foundation.value.Length.NAUTICAL_MILE; 029import static org.tquadrat.foundation.value.Time.HOUR; 030import static org.tquadrat.foundation.value.Time.SECOND; 031import static org.tquadrat.foundation.value.Time.WEEK; 032 033import java.math.BigDecimal; 034 035import org.apiguardian.api.API; 036import org.tquadrat.foundation.annotation.ClassVersion; 037import org.tquadrat.foundation.value.api.DimensionWithLinearConversion; 038 039/** 040 * <p>{@summary The various instances of speed …}</p> 041 * <p>Because speed is distance per time, the values for 042 * {@link #factor()} 043 * are calculated based on the values from 044 * {@link Length#factor()} 045 * and 046 * {@link Time#factor()}.</p> 047 * 048 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 049 * @version $Id: Speed.java 1072 2023-09-30 20:44:38Z tquadrat $ 050 * @since 0.0.4 051 * 052 * @UMLGraph.link 053 */ 054@SuppressWarnings( "NewClassNamingConvention" ) 055@ClassVersion( sourceVersion = "$Id: Speed.java 1072 2023-09-30 20:44:38Z tquadrat $" ) 056@API( status = STABLE, since = "0.0.4" ) 057public enum Speed implements DimensionWithLinearConversion 058{ 059 /*------------------*\ 060 ====** Enum Declaration **================================================= 061 \*------------------*/ 062 /** 063 * <p>{@summary Ångström per Week.} This is by far not a useful 064 * unit for speed, but it is the implementation of a famous instance of 065 * Murphy's Laws:</p> 066 * <cite>"Units are always provided in the most impractical form, e.g. 067 * a speed as Ångström per Week."</cite> 068 */ 069 @SuppressWarnings( "NonAsciiCharacters" ) 070 ÅNGSTRÖM_PER_WEEK( Length.ÅNGSTRÖM.factor().divide( WEEK.factor(), DECIMAL128 ), "Å/w" ), 071 072 /** 073 * Feet per second. 074 */ 075 FEET_PER_SECOND( FOOT.factor().divide( SECOND.factor(), DECIMAL128 ), "fps" ), 076 077 /** 078 * Knot (nautical mile per hour). 079 */ 080 KNOT( NAUTICAL_MILE.factor().divide( HOUR.factor(), DECIMAL128 ), "kn" ), 081 082 /** 083 * Kilometer per hour. 084 */ 085 KILOMETER_PER_HOUR( KILOMETER.factor().divide( HOUR.factor(), DECIMAL128 ), "km/h" ), 086 087 /** 088 * Meter per second. 089 */ 090 METER_PER_SECOND( BigDecimal.ONE, "m/s" ), 091 092 /** 093 * Mile per hour. 094 */ 095 MILE_PER_HOUR( MILE.factor().divide( HOUR.factor(), DECIMAL128 ), "mph" ); 096 097 /*------------*\ 098 ====** Attributes **======================================================= 099 \*------------*/ 100 /** 101 * The factor. 102 */ 103 private final BigDecimal m_Factor; 104 105 /** 106 * The unit symbol. 107 */ 108 private final String m_UnitSymbol; 109 110 /*--------------*\ 111 ====** Constructors **===================================================== 112 \*--------------*/ 113 /** 114 * Creates a new {@code Speed} instance. 115 * 116 * @param factor The factor. 117 * @param unitSymbol The unit symbol. 118 */ 119 private Speed( final BigDecimal factor, final String unitSymbol ) 120 { 121 m_Factor = factor.stripTrailingZeros(); 122 m_UnitSymbol = unitSymbol; 123 } // Speed() 124 125 /*---------*\ 126 ====** Methods **========================================================== 127 \*---------*/ 128 /** 129 * {@inheritDoc} 130 */ 131 @Override 132 @SuppressWarnings( "unchecked" ) 133 public final Speed baseUnit() { return METER_PER_SECOND; } 134 135 /** 136 * {@inheritDoc} 137 */ 138 @Override 139 public final BigDecimal factor() { return m_Factor; } 140 141 /** 142 * Returns the {@code Speed} instance for the given unit. 143 * 144 * @param unitSymbol The unit symbol. 145 * @return The respective instance. 146 * @throws IllegalArgumentException The given unit is unknown. 147 */ 148 public static final Speed forUnit( final String unitSymbol ) throws IllegalArgumentException 149 { 150 requireNotEmptyArgument( unitSymbol, "unit" ); 151 152 final var retValue = stream( values() ) 153 .filter( v -> v.unitSymbol().equals( unitSymbol ) ) 154 .findFirst() 155 .orElseThrow( () -> new IllegalArgumentException( format( MSG_UnknownUnit, unitSymbol ) ) ); 156 157 //---* Done *---------------------------------------------------------- 158 return retValue; 159 } // forUnit() 160 161 /** 162 * {@inheritDoc} 163 */ 164 @Override 165 public final String unitSymbol() { return m_UnitSymbol; } 166} 167// enum Speed 168 169/* 170 * End of File 171 */