All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.malliina.values.primitives.scala Maven / Gradle / Ivy

The newest version!
package com.malliina.values

import io.circe.{Codec, Decoder, Encoder}

import scala.annotation.targetName

opaque type NonNeg = Int

object NonNeg:
  given Codec[NonNeg] = Codec.from(
    Decoder.decodeInt.emap(i => apply(i).left.map(_.message)),
    Encoder.encodeInt.contramap(identity)
  )

  def apply(i: Int): Either[ErrorMessage, NonNeg] =
    if i >= 0 then Right(i)
    else Left(ErrorMessage(s"Value must be non-negative. Got '$i'."))

  extension (nn: NonNeg)
    def value: Int = nn
    def minus(other: Int): Either[ErrorMessage, NonNeg] = apply(value - other)
    def plus(other: Int): Either[ErrorMessage, NonNeg] = apply(value + other)
    @targetName("add")
    def +(other: NonNeg): NonNeg = value + other

/** A trimmed, non-blank string.
  */
opaque type NonBlank <: String = String

object NonBlank:
  def apply(s: String): Either[ErrorMessage, NonBlank] =
    val trimmed = s.trim
    if trimmed.nonEmpty then Right(trimmed)
    else Left(ErrorMessage("Must not be blank."))

  given Codec[NonBlank] = Codec.from(
    Decoder.decodeString.emap(i => apply(i).left.map(_.message)),
    Encoder.encodeString.contramap(identity)
  )




© 2015 - 2024 Weber Informatics LLC | Privacy Policy