From 5701ab6afa30141a6edeb0d2f838eb3af8481abc Mon Sep 17 00:00:00 2001 From: Mateusz Kubuszok Date: Fri, 15 Sep 2023 12:14:15 +0200 Subject: [PATCH] Introduce Path type intended for storing nested path in type level --- .../internal/compiletime/ChimneyTypesPlatform.scala | 13 +++++++++++-- .../internal/compiletime/ChimneyTypesPlatform.scala | 12 ++++++++++++ .../chimney/internal/compiletime/ChimneyTypes.scala | 12 ++++++++++++ .../scalaland/chimney/internal/runtime/Path.scala | 7 +++++++ 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 chimney/src/main/scala/io/scalaland/chimney/internal/runtime/Path.scala diff --git a/chimney/src/main/scala-2/io/scalaland/chimney/internal/compiletime/ChimneyTypesPlatform.scala b/chimney/src/main/scala-2/io/scalaland/chimney/internal/compiletime/ChimneyTypesPlatform.scala index c6614f645..c3a0e3a1e 100644 --- a/chimney/src/main/scala-2/io/scalaland/chimney/internal/compiletime/ChimneyTypesPlatform.scala +++ b/chimney/src/main/scala-2/io/scalaland/chimney/internal/compiletime/ChimneyTypesPlatform.scala @@ -174,7 +174,6 @@ private[compiletime] trait ChimneyTypesPlatform extends ChimneyTypes { this: Chi def apply[F <: runtime.PatcherFlags.Flag: Type, Flags <: runtime.PatcherFlags: Type] : Type[runtime.PatcherFlags.Enable[F, Flags]] = weakTypeTag[runtime.PatcherFlags.Enable[F, Flags]] - def unapply[A](A: Type[A]): Option[(?<[runtime.PatcherFlags.Flag], ?<[runtime.PatcherFlags])] = if (A.isCtor[runtime.PatcherFlags.Enable[?, ?]]) Some(A.param_<[runtime.PatcherFlags.Flag](0) -> A.param_<[runtime.PatcherFlags](1)) @@ -184,7 +183,6 @@ private[compiletime] trait ChimneyTypesPlatform extends ChimneyTypes { this: Chi def apply[F <: runtime.PatcherFlags.Flag: Type, Flags <: runtime.PatcherFlags: Type] : Type[runtime.PatcherFlags.Disable[F, Flags]] = weakTypeTag[runtime.PatcherFlags.Disable[F, Flags]] - def unapply[A](A: Type[A]): Option[(?<[runtime.PatcherFlags.Flag], ?<[runtime.PatcherFlags])] = if (A.isCtor[runtime.PatcherFlags.Disable[?, ?]]) Some(A.param_<[runtime.PatcherFlags.Flag](0) -> A.param_<[runtime.PatcherFlags](1)) @@ -199,5 +197,16 @@ private[compiletime] trait ChimneyTypesPlatform extends ChimneyTypes { this: Chi val MacrosLogging: Type[runtime.PatcherFlags.MacrosLogging] = weakTypeTag[runtime.PatcherFlags.MacrosLogging] } } + + object Path extends PathModule { + val Root: Type[runtime.Path.Root] = weakTypeTag[runtime.Path.Root] + object Select extends SelectModule { + def apply[Name <: String: Type, Instance <: runtime.Path: Type]: Type[runtime.Path.Select[Name, Instance]] = + weakTypeTag[runtime.Path.Select[Name, Instance]] + def unapply[A](A: Type[A]): Option[(?<[String], ?<[runtime.Path])] = + if (A.isCtor[runtime.Path.Select[?, ?]]) Some(A.param_<[String](0) -> A.param_<[runtime.Path](1)) + else scala.None + } + } } } diff --git a/chimney/src/main/scala-3/io/scalaland/chimney/internal/compiletime/ChimneyTypesPlatform.scala b/chimney/src/main/scala-3/io/scalaland/chimney/internal/compiletime/ChimneyTypesPlatform.scala index 0ad05667f..2267c859b 100644 --- a/chimney/src/main/scala-3/io/scalaland/chimney/internal/compiletime/ChimneyTypesPlatform.scala +++ b/chimney/src/main/scala-3/io/scalaland/chimney/internal/compiletime/ChimneyTypesPlatform.scala @@ -200,5 +200,17 @@ private[compiletime] trait ChimneyTypesPlatform extends ChimneyTypes { this: Chi val MacrosLogging: Type[runtime.PatcherFlags.MacrosLogging] = quoted.Type.of[runtime.PatcherFlags.MacrosLogging] } } + + object Path extends PathModule { + val Root: Type[runtime.Path.Root] = quoted.Type.of[runtime.Path.Root] + object Select extends SelectModule { + def apply[Name <: String: Type, Instance <: runtime.Path: Type]: Type[runtime.Path.Select[Name, Instance]] = + quoted.Type.of[runtime.Path.Select[Name, Instance]] + def unapply[A](tpe: Type[A]): Option[(?<[String], ?<[runtime.Path])] = tpe match + case '[runtime.Path.Select[name, instance]] => + Some((Type[name].as_?<[String], Type[instance].as_?<[runtime.Path])) + case _ => scala.None + } + } } } diff --git a/chimney/src/main/scala/io/scalaland/chimney/internal/compiletime/ChimneyTypes.scala b/chimney/src/main/scala/io/scalaland/chimney/internal/compiletime/ChimneyTypes.scala index e5247efe0..be59a5ebb 100644 --- a/chimney/src/main/scala/io/scalaland/chimney/internal/compiletime/ChimneyTypes.scala +++ b/chimney/src/main/scala/io/scalaland/chimney/internal/compiletime/ChimneyTypes.scala @@ -171,6 +171,18 @@ private[compiletime] trait ChimneyTypes { this: ChimneyDefinitions => } } + val Path: PathModule + trait PathModule { this: Path.type => + val Root: Type[runtime.Path.Root] + val Select: SelectModule + trait SelectModule + extends Type.Ctor2UpperBounded[ + String, + runtime.Path, + runtime.Path.Select + ] { this: Select.type => } + } + // You can `import ChimneyType.Implicits.*` in your shared code to avoid providing types manually, while avoiding conflicts // with implicit types seen in platform-specific scopes (which would happen if those implicits were always used). object Implicits { diff --git a/chimney/src/main/scala/io/scalaland/chimney/internal/runtime/Path.scala b/chimney/src/main/scala/io/scalaland/chimney/internal/runtime/Path.scala new file mode 100644 index 000000000..24f8edec4 --- /dev/null +++ b/chimney/src/main/scala/io/scalaland/chimney/internal/runtime/Path.scala @@ -0,0 +1,7 @@ +package io.scalaland.chimney.internal.runtime + +sealed abstract class Path +object Path { + final class Root extends Path + final class Select[Name <: String, Instance <: Path] extends Path +}