gs-std/src/main/scala/gs/std/v0/Size.scala
Pat Garrity 9abef2d8ce
All checks were successful
/ Build and Release Library (push) Successful in 1m30s
Some multi-module action.
2026-04-29 22:49:06 -05:00

102 lines
2.1 KiB
Scala

package gs.std.v0.core
/** Opaque type for collection sizes. Values are guaranteed to be 0 or greater.
*/
opaque type Size = Int
/** Opaque type for collection sizes. Values are guaranteed to be 0 or greater.
*/
object Size:
sealed trait Invalid
object Invalid extends Invalid
/** The size 0.
*/
final val Zero: Size = 0
/** The size 1.
*/
final val One: Size = 1
/** Express the given integer as a size.
*
* Throws an `IllegalArgumentException` if a negative value is given as
* input.
*
* @param value
* The input integer.
* @return
* The [[Size]] instance.
*/
def apply(value: Int): Size =
if value >= 0 then value
else throw new IllegalArgumentException("Size values must be 0 or greater.")
def validate(value: Int): Either[Invalid, Size] =
if value >= 0 then Right(value) else Left(Invalid)
/** Express the size of any collection.
*
* @param iter
* The collection.
* @return
* The size of the collection.
*/
def of(iter: Iterable[?]): Size = iter.size
/** Express the size of any array.
*
* @param arr
* The array.
* @return
* The size of the array.
*/
def of(arr: Array[?]): Size = arr.length
given CanEqual[Size, Size] = CanEqual.derived
given Ordering[Size] with
/** @inheritDocs
*/
def compare(
x: Size,
y: Size
): Int = x - y
extension (size: Size)
/** @return
* The underlying integer.
*/
def unwrap(): Int = size
/** @return
* The next value.
*/
def next(): Size = size + 1
/** @return
* The next value.
*/
def increment(): Size = size + 1
/** Add some size to this one.
*
* @param that
* The number to add.
* @return
* The sum of the numbers.
*/
def +(that: Size): Size = size + that
/** Multiply this size by some other size.
*
* @param that
* The number to multiply by.
* @return
* The product of the numbers.
*/
def *(that: Size): Size = size * that
end Size