diff --git a/crypto/js/src/main/scala/org/http4s/crypto/CryptoPlatform.scala b/crypto/js/src/main/scala/org/http4s/crypto/CryptoPlatform.scala index a26fc32..1ecf3c7 100644 --- a/crypto/js/src/main/scala/org/http4s/crypto/CryptoPlatform.scala +++ b/crypto/js/src/main/scala/org/http4s/crypto/CryptoPlatform.scala @@ -20,7 +20,12 @@ import cats.effect.kernel.Async import cats.effect.kernel.Sync private[crypto] trait CryptoCompanionPlatform { - implicit def forAsyncOrSync[F[_]](implicit F: Priority[Async[F], Sync[F]]): Crypto[F] = + + @deprecated("Preserved for bincompat", "0.2.3") + def forAsyncOrSync[F[_]](implicit F: Priority[Async[F], Sync[F]]): Crypto[F] = + forSync(F.join) + + implicit def forSync[F[_]](implicit F: Sync[F]): Crypto[F] = new UnsealedCrypto[F] { override def hash: Hash[F] = Hash[F] override def hmac: Hmac[F] = Hmac[F] diff --git a/crypto/js/src/main/scala/org/http4s/crypto/HashPlatform.scala b/crypto/js/src/main/scala/org/http4s/crypto/HashPlatform.scala index a0be931..30d60e9 100644 --- a/crypto/js/src/main/scala/org/http4s/crypto/HashPlatform.scala +++ b/crypto/js/src/main/scala/org/http4s/crypto/HashPlatform.scala @@ -16,26 +16,33 @@ package org.http4s.crypto +import cats.ApplicativeThrow import cats.MonadThrow import cats.effect.kernel.Async import cats.syntax.all._ import scodec.bits.ByteVector private[crypto] trait HashCompanionPlatform { - implicit def forAsyncOrMonadThrow[F[_]]( - implicit F: Priority[Async[F], MonadThrow[F]]): Hash[F] = + @deprecated("Preserved for bincompat", "0.2.3") + def forAsyncOrMonadThrow[F[_]](implicit F: Priority[Async[F], MonadThrow[F]]): Hash[F] = + forApplicativeThrow(F.join) + + implicit def forApplicativeThrow[F[_]](implicit F: ApplicativeThrow[F]): Hash[F] = if (facade.isNodeJSRuntime) new UnsealedHash[F] { override def digest(algorithm: HashAlgorithm, data: ByteVector): F[ByteVector] = - F.join[MonadThrow[F]].catchNonFatal { + F.catchNonFatal { val hash = facade.node.crypto.createHash(algorithm.toStringNodeJS) hash.update(data.toUint8Array) ByteVector.view(hash.digest()) } } else - F.getPreferred - .map { implicit F: Async[F] => + Some(F) + .collect { case f: Async[F] => f } + .fold( + throw new UnsupportedOperationException("Hash[F] on browsers requires Async[F]") + ) { implicit F: Async[F] => new UnsealedHash[F] { import facade.browser._ override def digest(algorithm: HashAlgorithm, data: ByteVector): F[ByteVector] = @@ -44,7 +51,5 @@ private[crypto] trait HashCompanionPlatform { .map(ByteVector.view) } } - .getOrElse(throw new UnsupportedOperationException( - "Hash[F] on browsers requires Async[F]")) } diff --git a/crypto/js/src/main/scala/org/http4s/crypto/HmacKeyGenPlatform.scala b/crypto/js/src/main/scala/org/http4s/crypto/HmacKeyGenPlatform.scala index a87b7f5..508d91e 100644 --- a/crypto/js/src/main/scala/org/http4s/crypto/HmacKeyGenPlatform.scala +++ b/crypto/js/src/main/scala/org/http4s/crypto/HmacKeyGenPlatform.scala @@ -24,36 +24,45 @@ import scodec.bits.ByteVector import scala.scalajs.js private[crypto] trait HmacKeyGenCompanionPlatform { - implicit def forAsyncOrSync[F[_]](implicit F0: Priority[Async[F], Sync[F]]): HmacKeyGen[F] = + @deprecated("Preserved for bincompat", "0.2.3") + def forAsyncOrSync[F[_]](implicit F0: Priority[Async[F], Sync[F]]): HmacKeyGen[F] = + forSync(F0.join) + + implicit def forSync[F[_]](implicit F: Sync[F]): HmacKeyGen[F] = if (facade.isNodeJSRuntime) new UnsealedHmacKeyGen[F] { import facade.node._ override def generateKey[A <: HmacAlgorithm](algorithm: A): F[SecretKey[A]] = - F0.fold { F => - F.async_[SecretKey[A]] { cb => - crypto.generateKey( - "hmac", - GenerateKeyOptions(algorithm.minimumKeyLength), - (err, key) => - cb( - Option(err) - .map(js.JavaScriptException) - .toLeft(SecretKeySpec(ByteVector.view(key.`export`()), algorithm))) - ) - } - } { F => - F.delay { - val key = - crypto.generateKeySync("hmac", GenerateKeyOptions(algorithm.minimumKeyLength)) - SecretKeySpec(ByteVector.view(key.`export`()), algorithm) + Some(F) + .collect { case f: Async[F] => f } + .fold { + F.delay[SecretKey[A]] { + val key = + crypto.generateKeySync("hmac", GenerateKeyOptions(algorithm.minimumKeyLength)) + SecretKeySpec(ByteVector.view(key.`export`()), algorithm) + } + } { F => + F.async_[SecretKey[A]] { cb => + crypto.generateKey( + "hmac", + GenerateKeyOptions(algorithm.minimumKeyLength), + (err, key) => + cb( + Option(err) + .map(js.JavaScriptException) + .toLeft(SecretKeySpec(ByteVector.view(key.`export`()), algorithm))) + ) + } } - } } else - F0.getPreferred - .map { implicit F: Async[F] => + Some(F) + .collect { case f: Async[F] => f } + .fold( + throw new UnsupportedOperationException("HmacKeyGen[F] on browsers requires Async[F]") + ) { implicit F => new UnsealedHmacKeyGen[F] { import facade.browser._ override def generateKey[A <: HmacAlgorithm](algorithm: A): F[SecretKey[A]] = @@ -70,7 +79,5 @@ private[crypto] trait HmacKeyGenCompanionPlatform { } yield SecretKeySpec(ByteVector.view(exported), algorithm) } } - .getOrElse(throw new UnsupportedOperationException( - "HmacKeyGen[F] on browsers requires Async[F]")) } diff --git a/crypto/js/src/main/scala/org/http4s/crypto/HmacPlatform.scala b/crypto/js/src/main/scala/org/http4s/crypto/HmacPlatform.scala index c2c29e3..d1da679 100644 --- a/crypto/js/src/main/scala/org/http4s/crypto/HmacPlatform.scala +++ b/crypto/js/src/main/scala/org/http4s/crypto/HmacPlatform.scala @@ -26,12 +26,16 @@ import scala.scalajs.js private[crypto] trait HmacPlatform[F[_]] private[crypto] trait HmacCompanionPlatform { - implicit def forAsyncOrApplicativeThrow[F[_]]( + + @deprecated("Preserved for bincompat", "0.2.3") + def forAsyncOrApplicativeThrow[F[_]]( implicit F0: Priority[Async[F], ApplicativeThrow[F]]): Hmac[F] = + forApplicativeThrow(F0.join) + + implicit def forApplicativeThrow[F[_]](implicit F: ApplicativeThrow[F]): Hmac[F] = if (facade.isNodeJSRuntime) new UnsealedHmac[F] { import facade.node._ - implicit val F: ApplicativeThrow[F] = F0.join[ApplicativeThrow[F]] override def digest(key: SecretKey[HmacAlgorithm], data: ByteVector): F[ByteVector] = key match { @@ -51,8 +55,11 @@ private[crypto] trait HmacCompanionPlatform { } else - F0.getPreferred - .map { implicit F: Async[F] => + Some(F) + .collect { case f: Async[F] => f } + .fold( + throw new UnsupportedOperationException("Hmac[F] on browsers requires Async[F]") + ) { implicit F: Async[F] => new UnsealedHmac[F] { import facade.browser._ override def digest( @@ -82,7 +89,4 @@ private[crypto] trait HmacCompanionPlatform { F.pure(SecretKeySpec(key, algorithm)) } } - .getOrElse(throw new UnsupportedOperationException( - "Hmac[F] on browsers requires Async[F]")) - } diff --git a/crypto/js/src/main/scala/org/http4s/crypto/Priority.scala b/crypto/js/src/main/scala/org/http4s/crypto/Priority.scala index be198b1..3997d6b 100644 --- a/crypto/js/src/main/scala/org/http4s/crypto/Priority.scala +++ b/crypto/js/src/main/scala/org/http4s/crypto/Priority.scala @@ -26,6 +26,7 @@ package org.http4s.crypto * This type can be useful for problems where multiple algorithms can be used, depending on the * type classes available. */ +@deprecated("Unneeded when P and F belong to the same hiearchy", "0.2.3") private[http4s] sealed trait Priority[+P, +F] { import Priority.{Fallback, Preferred} @@ -70,11 +71,13 @@ private[http4s] object Priority extends FindPreferred { } private[crypto] trait FindPreferred extends FindFallback { - implicit def preferred[P](implicit ev: P): Priority[P, Nothing] = + @deprecated("Priority is deprecated", "0.2.3") + def preferred[P](implicit ev: P): Priority[P, Nothing] = Priority.Preferred(ev) } private[crypto] trait FindFallback { - implicit def fallback[F](implicit ev: F): Priority[Nothing, F] = + @deprecated("Priority is deprecated", "0.2.3") + def fallback[F](implicit ev: F): Priority[Nothing, F] = Priority.Fallback(ev) }