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

langoustine-lsp_sjs1_3.0.0.20.source-code.newtype.scala Maven / Gradle / Ivy

There is a newer version: 0.0.22
Show newest version
/*
 * Copyright 2022 Neandertech
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package langoustine.lsp

private[lsp] trait BasicallyTheSame[A, T]:
  def apply(a: A): T
  def reverse(t: T): A

private[lsp] trait TotalWrapper[Newtype, Impl](using ev: Newtype =:= Impl):
  def raw(a: Newtype): Impl   = ev.apply(a)
  def apply(s: Impl): Newtype = ev.flip.apply(s)

  inline def unapply(s: Impl): Newtype = apply(s)
  given BasicallyTheSame[Impl, Newtype] with
    def apply(a: Impl)      = ev.flip(a)
    def reverse(a: Newtype) = ev(a)

  extension (a: Newtype)
    inline def value = raw(a)
    inline def into[X](inline other: TotalWrapper[X, Impl]): X =
      other.apply(raw(a))
    inline def map(inline f: Impl => Impl): Newtype = apply(f(raw(a)))
end TotalWrapper

private[lsp] inline given [A, T](using
    bts: BasicallyTheSame[T, A],
    ord: Ordering[A]
): Ordering[T] =
  Ordering.by(bts.apply)

private[lsp] trait OpaqueString[A](using A =:= String)
    extends TotalWrapper[A, String]
private[lsp] trait OpaqueInt[A](using A =:= Int) extends TotalWrapper[A, Int]

private[lsp] abstract class OpaqueNum[A](using A =:= Int)
    extends TotalWrapper[A, Int]

private[lsp] abstract class YesNo[A](using ev: Boolean =:= A):
  val Yes: A = ev.apply(true)
  val No: A  = ev.apply(false)
  given BasicallyTheSame[Boolean, A] with
    def apply(a: Boolean) = if a then Yes else No
    def reverse(a: A)     = a == Yes

  inline def apply(inline b: Boolean): A = ev.apply(b)

  extension (inline a: A)
    inline def value: Boolean = a == Yes
    inline def yes: Boolean   = a == Yes
end YesNo




© 2015 - 2024 Weber Informatics LLC | Privacy Policy