From 0650dd28b6bce37d15b2c05f83381405df75a8b4 Mon Sep 17 00:00:00 2001 From: Chris Davenport Date: Thu, 6 Feb 2020 11:23:38 -0800 Subject: [PATCH 1/5] Add Tagless Module --- .gitignore | 1 + build.sbt | 25 ++++++++---- .../fuuid/tagless/FUUIDGen.scala | 38 +++++++++++++++++++ 3 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 modules/tagless/src/main/scala/io/chrisdavenport/fuuid/tagless/FUUIDGen.scala diff --git a/.gitignore b/.gitignore index 87e7b850..2061a4ba 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ target/ tags .metals .bloop +project/metals.sbt diff --git a/build.sbt b/build.sbt index e9ea484b..9bca09ac 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType} lazy val fuuid = project.in(file(".")) .disablePlugins(MimaPlugin) .settings(commonSettings, releaseSettings, skipOnPublishSettings) - .aggregate(coreJS, coreJVM, doobie, http4s, circeJS, circeJVM/*, docs*/) + .aggregate(coreJS, coreJVM, taglessJS, taglessJVM, doobie, http4s, circeJS, circeJVM/*, docs*/) lazy val core = crossProject(JSPlatform, JVMPlatform) .crossType(CrossType.Pure) @@ -13,10 +13,21 @@ lazy val core = crossProject(JSPlatform, JVMPlatform) name := "fuuid" ) - lazy val coreJS = core.js lazy val coreJVM = core.jvm +lazy val tagless = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("modules/tagless")) + .settings(commonSettings, releaseSettings, mimaSettings) + .dependsOn(core) + .settings( + name := "fuuid-tagless" + ) + +lazy val taglessJS = tagless.js +lazy val taglessJVM = tagless.jvm + lazy val doobie = project.in(file("modules/doobie")) .settings(commonSettings, releaseSettings, mimaSettings) .settings( @@ -77,7 +88,7 @@ lazy val docs = project.in(file("modules/docs")) .dependsOn(coreJVM, http4s, doobie, circeJVM) val catsV = "2.1.0" //https://github.com/typelevel/cats/releases -val catsEffectV = "2.0.0" //https://github.com/typelevel/cats-effect/releases +val catsEffectV = "2.1.0" //https://github.com/typelevel/cats-effect/releases val specs2V = "4.8.3" //https://github.com/etorreborre/specs2/releases val disciplineSpecs2V = "1.0.0" val circeV = "0.13.0-RC1" //https://github.com/circe/circe/releases @@ -95,12 +106,10 @@ lazy val contributors = Seq( lazy val commonSettings = Seq( organization := "io.chrisdavenport", - scalaVersion := "2.13.0", - crossScalaVersions := Seq(scalaVersion.value, "2.12.8"), - - scalacOptions += "-Yrangepos", + scalaVersion := "2.13.1", + crossScalaVersions := Seq(scalaVersion.value, "2.12.10"), - addCompilerPlugin("org.typelevel" % "kind-projector" % "0.10.3" cross CrossVersion.binary), + addCompilerPlugin("org.typelevel" % "kind-projector" % "0.11.0" cross CrossVersion.full), addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1"), libraryDependencies ++= Seq( "org.scala-lang" % "scala-reflect" % scalaVersion.value, diff --git a/modules/tagless/src/main/scala/io/chrisdavenport/fuuid/tagless/FUUIDGen.scala b/modules/tagless/src/main/scala/io/chrisdavenport/fuuid/tagless/FUUIDGen.scala new file mode 100644 index 00000000..cd6e5a38 --- /dev/null +++ b/modules/tagless/src/main/scala/io/chrisdavenport/fuuid/tagless/FUUIDGen.scala @@ -0,0 +1,38 @@ +package io.chrisdavenport.fuuid.tagless + +import io.chrisdavenport.fuuid.FUUID +import java.util.UUID +import cats.implicits._ +import cats.effect.Sync + +trait FUUIDGen[F[_]]{ + /** + * Creates a Random FUUID + */ + def random: F[FUUID] + /** + * Creates an FUUID from a String, if it is valid + */ + def fromString(s: String): F[FUUID] + /** + * Creates an FUUID from a UUID + */ + def fromUUID(uuid: UUID): F[FUUID] + /** + * Creates a new name-based UUIDv5. NOTE: Not implemented for Scala.js! + **/ + def nameBased(namespace: FUUID, name: String): F[FUUID] +} + +object FUUIDGen { + def apply[F[_]](implicit ev: FUUIDGen[F]): FUUIDGen[F] = ev + + implicit def fromSync[F[_]: Sync]: FUUIDGen[F] = new SyncFUUIDGen[F] + + private class SyncFUUIDGen[F[_]: Sync] extends FUUIDGen[F]{ + def random: F[FUUID] = FUUID.randomFUUID[F] + def fromString(s: String): F[FUUID] = FUUID.fromStringF[F](s) + def fromUUID(uuid: UUID): F[FUUID] = FUUID.fromUUID(uuid).pure[F] + def nameBased(namespace: FUUID, name: String): F[FUUID] = FUUID.nameBased[F](namespace, name) + } +} \ No newline at end of file From 3396f7c73e0e33a3eb45790ec5daa3c19a63c4a7 Mon Sep 17 00:00:00 2001 From: Chris Davenport Date: Thu, 6 Feb 2020 11:29:30 -0800 Subject: [PATCH 2/5] Move to top-level --- build.sbt | 12 ------------ .../scala/io/chrisdavenport/fuuid}/FUUIDGen.scala | 3 +-- 2 files changed, 1 insertion(+), 14 deletions(-) rename modules/{tagless/src/main/scala/io/chrisdavenport/fuuid/tagless => core/src/main/scala/io/chrisdavenport/fuuid}/FUUIDGen.scala (92%) diff --git a/build.sbt b/build.sbt index 9bca09ac..6f4e62e1 100644 --- a/build.sbt +++ b/build.sbt @@ -16,18 +16,6 @@ lazy val core = crossProject(JSPlatform, JVMPlatform) lazy val coreJS = core.js lazy val coreJVM = core.jvm -lazy val tagless = crossProject(JSPlatform, JVMPlatform) - .crossType(CrossType.Pure) - .in(file("modules/tagless")) - .settings(commonSettings, releaseSettings, mimaSettings) - .dependsOn(core) - .settings( - name := "fuuid-tagless" - ) - -lazy val taglessJS = tagless.js -lazy val taglessJVM = tagless.jvm - lazy val doobie = project.in(file("modules/doobie")) .settings(commonSettings, releaseSettings, mimaSettings) .settings( diff --git a/modules/tagless/src/main/scala/io/chrisdavenport/fuuid/tagless/FUUIDGen.scala b/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala similarity index 92% rename from modules/tagless/src/main/scala/io/chrisdavenport/fuuid/tagless/FUUIDGen.scala rename to modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala index cd6e5a38..8388298d 100644 --- a/modules/tagless/src/main/scala/io/chrisdavenport/fuuid/tagless/FUUIDGen.scala +++ b/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala @@ -1,6 +1,5 @@ -package io.chrisdavenport.fuuid.tagless +package io.chrisdavenport.fuuid -import io.chrisdavenport.fuuid.FUUID import java.util.UUID import cats.implicits._ import cats.effect.Sync From 9033bf08737a26d4b3c4f7ff820ed3598a423449 Mon Sep 17 00:00:00 2001 From: Chris Davenport Date: Thu, 6 Feb 2020 11:35:53 -0800 Subject: [PATCH 3/5] Better Documentation and Implicit Annotations --- build.sbt | 2 +- .../src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 6f4e62e1..df9d63aa 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType} lazy val fuuid = project.in(file(".")) .disablePlugins(MimaPlugin) .settings(commonSettings, releaseSettings, skipOnPublishSettings) - .aggregate(coreJS, coreJVM, taglessJS, taglessJVM, doobie, http4s, circeJS, circeJVM/*, docs*/) + .aggregate(coreJS, coreJVM, doobie, http4s, circeJS, circeJVM/*, docs*/) lazy val core = crossProject(JSPlatform, JVMPlatform) .crossType(CrossType.Pure) diff --git a/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala b/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala index 8388298d..5ee96548 100644 --- a/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala +++ b/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala @@ -4,6 +4,14 @@ import java.util.UUID import cats.implicits._ import cats.effect.Sync +/** + * This trait is an F-algebra representation of the ability to generate FUUID's. + * + * At some edge a Sync is required in order to populate the randomness when required. + */ +@scala.annotation.implicitNotFound("""Cannot find implicit value for FUUIDGen[${F}]. +Building this implicit value depends on having an implicit +Sync[${F}] or some equivalent type.""") trait FUUIDGen[F[_]]{ /** * Creates a Random FUUID From cba924385b747e1eef5d6689c322880e330a76da Mon Sep 17 00:00:00 2001 From: Chris Davenport Date: Thu, 6 Feb 2020 11:36:40 -0800 Subject: [PATCH 4/5] Upgrade http4s --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index df9d63aa..825d7b38 100644 --- a/build.sbt +++ b/build.sbt @@ -80,7 +80,7 @@ val catsEffectV = "2.1.0" //https://github.com/typelevel/cats-effect/releas val specs2V = "4.8.3" //https://github.com/etorreborre/specs2/releases val disciplineSpecs2V = "1.0.0" val circeV = "0.13.0-RC1" //https://github.com/circe/circe/releases -val http4sV = "0.21.0-RC2" //https://github.com/http4s/http4s/releases +val http4sV = "0.21.0-RC4" //https://github.com/http4s/http4s/releases val doobieV = "0.8.8" //https://github.com/tpolecat/doobie/releases val scalaJavaTimeV = "2.0.0-RC3" // https://github.com/cquiroz/scala-java-time/releases val testContainersSpecs2V = "0.2.0-M2" // From 2120acd9d89fad4769c3f9ef182e0a25ddbf4b2c Mon Sep 17 00:00:00 2001 From: Christopher Davenport Date: Thu, 6 Feb 2020 13:52:24 -0800 Subject: [PATCH 5/5] simpler naming --- .../src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala b/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala index 5ee96548..dd369bb2 100644 --- a/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala +++ b/modules/core/src/main/scala/io/chrisdavenport/fuuid/FUUIDGen.scala @@ -34,7 +34,8 @@ trait FUUIDGen[F[_]]{ object FUUIDGen { def apply[F[_]](implicit ev: FUUIDGen[F]): FUUIDGen[F] = ev - implicit def fromSync[F[_]: Sync]: FUUIDGen[F] = new SyncFUUIDGen[F] + // Sync f => class FUUIDGen f + implicit def instance[F[_]: Sync]: FUUIDGen[F] = new SyncFUUIDGen[F] private class SyncFUUIDGen[F[_]: Sync] extends FUUIDGen[F]{ def random: F[FUUID] = FUUID.randomFUUID[F] @@ -42,4 +43,4 @@ object FUUIDGen { def fromUUID(uuid: UUID): F[FUUID] = FUUID.fromUUID(uuid).pure[F] def nameBased(namespace: FUUID, name: String): F[FUUID] = FUUID.nameBased[F](namespace, name) } -} \ No newline at end of file +}