From 453806576da0baff2c7de98bc3017a96d2c4f813 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Mon, 9 Mar 2020 15:05:42 -0500 Subject: [PATCH] [ci skip] Add documentation for replacing default calculator --- docs/customize.rst | 12 ++- docs/customize/calculators.rst | 75 ++++++++++++++ docs/reference.rst | 1 + docs/reference/calculators.rst | 168 +++++++++++++++++++++++++++++++ src/Math/CalculatorInterface.php | 2 +- src/Math/RoundingMode.php | 4 - 6 files changed, 254 insertions(+), 8 deletions(-) create mode 100644 docs/customize/calculators.rst create mode 100644 docs/reference/calculators.rst diff --git a/docs/customize.rst b/docs/customize.rst index 637c3c9..a539c35 100644 --- a/docs/customize.rst +++ b/docs/customize.rst @@ -10,12 +10,13 @@ Customization customize/ordered-time-codec customize/timestamp-first-comb-codec + customize/calculators ramsey/uuid offers a variety of ways to modify the standard behavior of the -library through dependency injection. Using `UuidFactory`_, `FeatureSet`_, and +library through dependency injection. Using `FeatureSet`_, `UuidFactory`_, and :php:meth:`Uuid::setFactory() `, you are able -to replace just about any `codec`_, `builder`_, `converter`_, `provider`_, -`generator`_, and more. +to replace just about any `builder`_, `codec`_, `converter`_, `generator`_, +`provider`_, and more. Ordered-time Codec The ordered-time codec exists to rearrange the bytes of a version 1, @@ -27,6 +28,11 @@ Timestamp-first COMB Codec with a timestamp, so that the UUID becomes monotonically increasing. To learn more, see :ref:`customize.timestamp-first-comb-codec`. +Using a Custom Calculator + It's possible to replace the default calculator ramsey/uuid uses. If your + requirements require a different solution for making calculations, see + :ref:`customize.calculators`. + .. _UuidFactory: https://github.com/ramsey/uuid/blob/master/src/UuidFactory.php .. _FeatureSet: https://github.com/ramsey/uuid/blob/master/src/FeatureSet.php diff --git a/docs/customize/calculators.rst b/docs/customize/calculators.rst new file mode 100644 index 0000000..a2bcea0 --- /dev/null +++ b/docs/customize/calculators.rst @@ -0,0 +1,75 @@ +.. _customize.calculators: + +========================= +Using a Custom Calculator +========================= + +By default, ramsey/uuid uses `brick/math`_ as its internal calculator. However, +you may change the calculator, if your needs require something else. + +To swap the default calculator with your custom one, first make an adapter that +wraps your custom calculator and implements +:php:interface:`Ramsey\\Uuid\\Math\\CalculatorInterface`. This might look +something like this: + +.. code-block:: php + :caption: Create a custom calculator wrapper that implements CalculatorInterface + :name: customize.calculators.wrapper-example + + namespace MyProject; + + use Other\OtherCalculator; + use Ramsey\Uuid\Math\CalculatorInterface; + use Ramsey\Uuid\Type\Integer as IntegerObject; + use Ramsey\Uuid\Type\NumberInterface; + + class MyUuidCalculator implements CalculatorInterface + { + private $internalCalculator; + + public function __construct(OtherCalculator $customCalculator) + { + $this->internalCalculator = $customCalculator; + } + + public function add(NumberInterface $augend, NumberInterface ...$addends): NumberInterface + { + $value = $augend->toString(); + + foreach ($addends as $addend) { + $value = $this->internalCalculator->plus($value, $addend->toString()); + } + + return new IntegerObject($value); + } + + /* ... Class truncated for brevity ... */ + + } + +The easiest way to use your custom calculator wrapper is to instantiate a new +FeatureSet, set the calculator on it, and pass the FeatureSet into a new +UuidFactory. Using the factory, you may then generate and work with UUIDs, using +your custom calculator. + +.. code-block:: php + :caption: Use your custom calculator wrapper when working with UUIDs + :name: customize.calculators.use-wrapper-example + + use MyProject\MyUuidCalculator; + use Other\OtherCalculator; + use Ramsey\Uuid\FeatureSet; + use Ramsey\Uuid\UuidFactory; + + $otherCalculator = new OtherCalculator(); + $myUuidCalculator = new MyUuidCalculator($otherCalculator); + + $featureSet = new FeatureSet(); + $featureSet->setCalculator($myUuidCalculator); + + $factory = new UuidFactory($featureSet); + + $uuid = $factory->uuid1(); + + +.. _brick/math: https://github.com/brick/math diff --git a/docs/reference.rst b/docs/reference.rst index fc02b7b..4633089 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -27,3 +27,4 @@ Reference reference/exceptions reference/helper reference/name-based-namespaces + reference/calculators diff --git a/docs/reference/calculators.rst b/docs/reference/calculators.rst new file mode 100644 index 0000000..9f9167d --- /dev/null +++ b/docs/reference/calculators.rst @@ -0,0 +1,168 @@ +.. _reference.calculators: + +=========== +Calculators +=========== + +.. php:namespace:: Ramsey\Uuid\Math + +.. php:interface:: CalculatorInterface + + Provides functionality for performing mathematical calculations. + + .. php:method:: add($augend, ...$addends) + + :param Ramsey\\Uuid\\Type\\NumberInterface $augend: The first addend (the integer being added to) + :param Ramsey\\Uuid\\Type\\NumberInterface ...$addends: The additional integers to a add to the augend + :returns: The sum of all the parameters + :returntype: Ramsey\\Uuid\\Type\\NumberInterface + + .. php:method:: subtract($minuend, ...$subtrahends) + + :param Ramsey\\Uuid\\Type\\NumberInterface $minuend: The integer being subtracted from + :param Ramsey\\Uuid\\Type\\NumberInterface ...$subtrahends: The integers to subtract from the minuend + :returns: The difference after subtracting all parameters + :returntype: Ramsey\\Uuid\\Type\\NumberInterface + + .. php:method:: multiply($multiplicand, ...$multipliers) + + :param Ramsey\\Uuid\\Type\\NumberInterface $multiplicand: The integer to be multiplied + :param Ramsey\\Uuid\\Type\\NumberInterface ...$multipliers: The factors by which to multiply the multiplicand + :returns: The product of multiplying all the provided parameters + :returntype: Ramsey\\Uuid\\Type\\NumberInterface + + .. php:method:: divide($roundingMode, $scale, $dividend, ...$divisors) + + :param int $roundingMode: The strategy for rounding the quotient; one of the :php:class:`Ramsey\\Uuid\\Math\\RoundingMode` constants + :param int $scale: The scale to use for the operation + :param Ramsey\\Uuid\\Type\\NumberInterface $dividend: The integer to be divided + :param Ramsey\\Uuid\\Type\\NumberInterface ...$divisors: The integers to divide ``$dividend`` by, in the order in which the division operations should take place (left-to-right) + :returns: The quotient of dividing the provided parameters left-to-right + :returntype: Ramsey\\Uuid\\Type\\NumberInterface + + + .. php:method:: fromBase($value, $base) + + Converts a value from an arbitrary base to a base-10 integer value. + + :param string $value: The value to convert + :param int $base: The base to convert from (i.e., 2, 16, 32, etc.) + :returns: The base-10 integer value of the converted value + :returntype: Ramsey\\Uuid\\Type\\Integer + + .. php:method:: toBase($value, $base) + + Converts a base-10 integer value to an arbitrary base. + + :param Ramsey\\Uuid\\Type\\Integer $value: The integer value to convert + :param int $base: The base to convert to (i.e., 2, 16, 32, etc.) + :returns: The value represented in the specified base + :returntype: ``string`` + + .. php:method:: toHexadecimal($value) + + Converts an Integer instance to a Hexadecimal instance. + + :param Ramsey\\Uuid\\Type\\Integer $value: The Integer to convert to Hexadecimal + :returntype: Ramsey\\Uuid\\Type\\Hexadecimal + + .. php:method:: toInteger($value) + + Converts a Hexadecimal instance to an Integer instance. + + :param Ramsey\\Uuid\\Type\\Hexadecimal $value: The Hexadecimal to convert to Integer + :returntype: Ramsey\\Uuid\\Type\\Integer + + +.. php:class:: RoundingMode + + .. php:const:: UNNECESSARY + + Asserts that the requested operation has an exact result, hence no + rounding is necessary. + + .. php:const:: UP + + Rounds away from zero. + + Always increments the digit prior to a nonzero discarded fraction. + Note that this rounding mode never decreases the magnitude of the + calculated value. + + .. php:const:: DOWN + + Rounds towards zero. + + Never increments the digit prior to a discarded fraction (i.e., + truncates). Note that this rounding mode never increases the magnitude of + the calculated value. + + .. php:const:: CEILING + + Rounds towards positive infinity. + + If the result is positive, behaves as for :php:const:`UP + `; if negative, behaves as for + :php:const:`DOWN `. Note that + this rounding mode never decreases the calculated value. + + .. php:const:: FLOOR + + Rounds towards negative infinity. + + If the result is positive, behave as for :php:const:`DOWN + `; if negative, behave as for + :php:const:`UP `. Note that this + rounding mode never increases the calculated value. + + .. php:const:: HALF_UP + + Rounds towards "nearest neighbor" unless both neighbors are equidistant, + in which case round up. + + Behaves as for :php:const:`UP ` if + the discarded fraction is >= 0.5; otherwise, behaves as for + :php:const:`DOWN `. Note that + this is the rounding mode commonly taught at school. + + .. php:const:: HALF_DOWN + + Rounds towards "nearest neighbor" unless both neighbors are equidistant, + in which case round down. + + Behaves as for :php:const:`UP ` if + the discarded fraction is > 0.5; otherwise, behaves as for + :php:const:`DOWN `. + + .. php:const:: HALF_CEILING + + Rounds towards "nearest neighbor" unless both neighbors are equidistant, + in which case round towards positive infinity. + + If the result is positive, behaves as for :php:const:`HALF_UP + `; if negative, behaves as + for :php:const:`HALF_DOWN `. + + .. php:const:: HALF_FLOOR + + Rounds towards "nearest neighbor" unless both neighbors are equidistant, + in which case round towards negative infinity. + + If the result is positive, behaves as for :php:const:`HALF_DOWN + `; if negative, behaves as + for :php:const:`HALF_UP `. + + .. php:const:: HALF_EVEN + + Rounds towards the "nearest neighbor" unless both neighbors are + equidistant, in which case rounds towards the even neighbor. + + Behaves as for :php:const:`HALF_UP ` + if the digit to the left of the discarded fraction is odd; behaves as + for :php:const:`HALF_DOWN ` + if it's even. + + Note that this is the rounding mode that statistically minimizes + cumulative error when applied repeatedly over a sequence of calculations. + It is sometimes known as "Banker's rounding", and is chiefly used in the + USA. diff --git a/src/Math/CalculatorInterface.php b/src/Math/CalculatorInterface.php index f2dbd13..f03645d 100644 --- a/src/Math/CalculatorInterface.php +++ b/src/Math/CalculatorInterface.php @@ -61,7 +61,7 @@ interface CalculatorInterface * @param int $roundingMode The RoundingMode constant to use for this operation * @param int $scale The scale to use for this operation * @param NumberInterface $dividend The integer to be divided - * @param NumberInterface ...$divisors + * @param NumberInterface ...$divisors The integers to divide $dividend by, in * the order in which the division operations should take place * (left-to-right) * diff --git a/src/Math/RoundingMode.php b/src/Math/RoundingMode.php index 82f1cb7..e710270 100644 --- a/src/Math/RoundingMode.php +++ b/src/Math/RoundingMode.php @@ -56,10 +56,6 @@ final class RoundingMode /** * Asserts that the requested operation has an exact result, hence no * rounding is necessary. - * - * If this rounding mode is specified on an operation that yields a result - * that cannot be represented at the requested scale, a - * RoundingNecessaryException is thrown. */ public const UNNECESSARY = 0;