001/*
002 * ============================================================================
003 * Copyright © 2002-2026 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.lang.value;
019
020import static org.apiguardian.api.API.Status.STABLE;
021import static org.tquadrat.foundation.lang.value.DimensionedValue.MATH_CONTEXT;
022
023import java.math.BigDecimal;
024import java.util.function.UnaryOperator;
025
026import org.apiguardian.api.API;
027import org.tquadrat.foundation.annotation.ClassVersion;
028
029/**
030 *  <p>{@summary The implementations of this interface are used to give
031 *  (numerical) values a dimension and a measuring unit.} So {@code 3.1415} is
032 *  just a number, but it could also stand for a length
033 *  ({@code 3.1415&nbsp;m}), a time ({@code 3.1415&nbsp;s}) or even the fuel
034 *  consumption of a car ({@code 3.1415&nbsp;l/100&nbsp;km}). Depending on the
035 *  dimension, different values could be equal:</p>
036 *  <pre><code>1.0&nbsp;m == 100.0&nbsp;cm</code></pre>
037 *  <p>and should be treated as such.</p>
038 *  <p>This interface should be implemented as
039 *  {@link Enum enum}s,
040 *  where the enum values are the units, and as such they should provide a
041 *  method to retrieve an {@code enum} value (a unit) by the respective
042 *  {@linkplain #unitSymbol() symbol}.</p>
043 *  <p>It is a generalisation for dimensions that are converted by simple
044 *  division or multiplication of a factor, as for length or speed.</p>
045 *
046 *  @author Thomas Thrien - thomas.thrien@tquadrat.org
047 *  @version $Id: DimensionWithLinearConversion.java 1295 2026-10-18 12:34:27Z tquadrat $
048 *  @since 0.25.1
049 *
050 *  @UMLGraph.link
051 */
052@ClassVersion( sourceVersion = "$Id: DimensionWithLinearConversion.java 1295 2026-10-18 12:34:27Z tquadrat $" )
053@API( status = STABLE, since = "0.25.1" )
054public interface DimensionWithLinearConversion extends Dimension
055{
056        /*---------*\
057    ====** Methods **==========================================================
058        \*---------*/
059    /**
060     *  <p>{@summary Returns the factor that is used to convert a value from
061     *  this unit to the base unit.}</p>
062     *  <p>For length, if you have to convert a Centimeter value to Meter, you
063     *  will divide that by 100 or multiply it with a <i>factor</i> of
064     *  0.01.</p>
065     *  <p>For the base unit, the factor is 1.0.</p>
066     *
067     *  @return The factor.
068     *
069     *  @see #baseUnit()
070     */
071    public BigDecimal factor();
072
073    /**
074     * {@inheritDoc}
075     */
076    @Override
077    public default UnaryOperator<BigDecimal> fromBase()
078    {
079        final UnaryOperator<BigDecimal> retValue = base -> base.divide( factor(), MATH_CONTEXT );
080
081        //---* Done *----------------------------------------------------------
082        return retValue;
083    }   //  fromBase()
084
085    /**
086     *  <p>{@summary Returns the conversion that is used to convert a value
087     *  from this unit to the base unit.}</p>
088     *
089     *  @return The conversion.
090     */
091    @Override
092    public default UnaryOperator<BigDecimal> toBase()
093    {
094        final UnaryOperator<BigDecimal> retValue = value -> value.multiply( factor() );
095
096        //---* Done *----------------------------------------------------------
097        return retValue;
098    }   //  toBase()
099}
100//  interface DimensionWithLinearConversion
101
102/*
103 *  End of File
104 */