diff --git a/core/common/src/main/scala/org/typelevel/otel4s/context/Context.scala b/core/common/src/main/scala/org/typelevel/otel4s/context/Context.scala index b0945f0c1..a9259c9eb 100644 --- a/core/common/src/main/scala/org/typelevel/otel4s/context/Context.scala +++ b/core/common/src/main/scala/org/typelevel/otel4s/context/Context.scala @@ -17,10 +17,8 @@ package org.typelevel.otel4s package context -trait Context[C] { +trait Context[C] { outer => type Key[A] <: context.Key[A] - type KeyCreationBounds[_[_]] - type KeyTypeBounds[_] def get[A](ctx: C)(key: Key[A]): Option[A] @@ -31,11 +29,23 @@ trait Context[C] { def root: C - def uniqueKey[F[_]: KeyCreationBounds, A: KeyTypeBounds]( - name: String - ): F[Key[A]] + class Ops(ctx: C) { + def get[A](key: Key[A]): Option[A] = + outer.get(ctx)(key) + def getOrElse[A](key: Key[A], default: => A): A = + outer.getOrElse(ctx)(key, default) + def updated[A](key: Key[A], value: A): C = + outer.updated(ctx)(key, value) + } } object Context { + type Keyed[C, K[_]] = Context[C] { type Key[A] = K[A] } + def apply[C](implicit c: Context[C]): Context[C] = c + + object Implicits { + implicit def mkOps[C](ctx: C)(implicit c: Context[C]): c.Ops = + new c.Ops(ctx) + } } diff --git a/core/common/src/main/scala/org/typelevel/otel4s/context/Key.scala b/core/common/src/main/scala/org/typelevel/otel4s/context/Key.scala index dd583f788..73cb8c3de 100644 --- a/core/common/src/main/scala/org/typelevel/otel4s/context/Key.scala +++ b/core/common/src/main/scala/org/typelevel/otel4s/context/Key.scala @@ -23,8 +23,10 @@ trait Key[A] { } object Key { - sealed trait NoBounds[+A] - object NoBounds { - implicit object Instance extends NoBounds[Nothing] + trait Provider[F[_], K[_]] { + def uniqueKey[A](name: String): F[K[A]] + } + object Provider { + def apply[F[_], K[_]](implicit p: Provider[F, K]): Provider[F, K] = p } } diff --git a/core/common/src/main/scala/org/typelevel/otel4s/context/transparent/OpenContext.scala b/core/common/src/main/scala/org/typelevel/otel4s/context/transparent/OpenContext.scala deleted file mode 100644 index 59a33283c..000000000 --- a/core/common/src/main/scala/org/typelevel/otel4s/context/transparent/OpenContext.scala +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 Typelevel - * - * 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 org.typelevel.otel4s.context -package transparent - -import cats.effect.Sync - -import scala.reflect.ClassTag - -final case class OpenContext private (contents: Map[TypedKey[_], Any]) { - def get[A](key: TypedKey[A]): Option[A] = - contents.get(key).map(_.asInstanceOf[A]) - def getOrElse[A](key: TypedKey[A], default: => A): A = - get(key).getOrElse(default) - def updated[A](key: TypedKey[A], value: A): OpenContext = - OpenContext(contents.updated(key, value)) -} - -object OpenContext { - val root: OpenContext = apply(Map.empty) - - implicit object Ctx extends Context[OpenContext] { - type Key[A] = TypedKey[A] - type KeyCreationBounds[F[_]] = Sync[F] - type KeyTypeBounds[A] = ClassTag[A] - - def get[A](ctx: OpenContext)(key: TypedKey[A]): Option[A] = - ctx.get(key) - def updated[A](ctx: OpenContext)(key: TypedKey[A], value: A): OpenContext = - ctx.updated(key, value) - def root: OpenContext = OpenContext.root - def uniqueKey[F[_]: Sync, A: ClassTag](name: String): F[TypedKey[A]] = - TypedKey.unique(name) - } -} diff --git a/core/common/src/main/scala/org/typelevel/otel4s/context/transparent/TypedKey.scala b/core/common/src/main/scala/org/typelevel/otel4s/context/transparent/TypedKey.scala deleted file mode 100644 index 0658520ba..000000000 --- a/core/common/src/main/scala/org/typelevel/otel4s/context/transparent/TypedKey.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2022 Typelevel - * - * 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 org.typelevel.otel4s.context -package transparent - -import cats.effect.Sync - -import scala.reflect.ClassTag - -final class TypedKey[A] private (val name: String)(implicit - val classTag: ClassTag[A] -) extends Key[A] { - override def toString: String = - s"Key[${TypedKey.renderType(classTag.runtimeClass)}]($name)" -} - -object TypedKey { - def unique[F[_]: Sync, A: ClassTag](name: String): F[TypedKey[A]] = - Sync[F].delay(new TypedKey(name)) - - private def renderType(cls: Class[_]): String = { - if (cls.isArray) s"Array[${renderType(cls.getComponentType)}]" - else if (cls == classOf[AnyRef]) "AnyRef|Any" - else cls.getName - } -} diff --git a/core/common/src/main/scala/org/typelevel/otel4s/context/vault/VaultContext.scala b/core/common/src/main/scala/org/typelevel/otel4s/context/vault/VaultContext.scala index 4134af5a9..69609af44 100644 --- a/core/common/src/main/scala/org/typelevel/otel4s/context/vault/VaultContext.scala +++ b/core/common/src/main/scala/org/typelevel/otel4s/context/vault/VaultContext.scala @@ -21,8 +21,7 @@ package vault import cats.Functor import cats.effect.Unique import cats.syntax.functor._ -import org.typelevel.vault.{Key => VaultKey} -import org.typelevel.vault.Vault +import org.typelevel.vault.{Vault, Key => VaultKey} final case class VaultContext(vault: Vault) { def get[A](key: VaultContext.Key[A]): Option[A] = @@ -41,33 +40,22 @@ object VaultContext extends (Vault => VaultContext) { object Key { def unique[F[_]: Functor: Unique, A](name: String): F[Key[A]] = VaultKey.newKey[F, A].map(new Key[A](name, _)) + + implicit def provider[F[_]: Functor: Unique]: context.Key.Provider[F, Key] = + new context.Key.Provider[F, Key] { + def uniqueKey[A](name: String): F[Key[A]] = unique(name) + } } val root: VaultContext = apply(Vault.empty) - final case class UniqueFunctor[F[_]](functor: Functor[F], unique: Unique[F]) - object UniqueFunctor { - implicit def summon[F[_]: Functor: Unique]: UniqueFunctor[F] = - apply(implicitly, implicitly) - } - implicit object Ctx extends Context[VaultContext] { type Key[A] = VaultContext.Key[A] - type KeyCreationBounds[F[_]] = UniqueFunctor[F] - type KeyTypeBounds[A] = context.Key.NoBounds[A] def get[A](ctx: VaultContext)(key: Key[A]): Option[A] = ctx.get(key) def updated[A](ctx: VaultContext)(key: Key[A], value: A): VaultContext = ctx.updated(key, value) def root: VaultContext = VaultContext.root - def uniqueKey[F[_]: UniqueFunctor, A: context.Key.NoBounds]( - name: String - ): F[Key[A]] = { - val uf = implicitly[UniqueFunctor[F]] - implicit def functor: Functor[F] = uf.functor - implicit def unique: Unique[F] = uf.unique - VaultContext.Key.unique(name) - } } } diff --git a/java/common/src/main/scala/org/typelevel/otel4s/java/context/Context.scala b/java/common/src/main/scala/org/typelevel/otel4s/java/context/Context.scala index 249a88618..c2862191f 100644 --- a/java/common/src/main/scala/org/typelevel/otel4s/java/context/Context.scala +++ b/java/common/src/main/scala/org/typelevel/otel4s/java/context/Context.scala @@ -56,6 +56,11 @@ object Context { object Key { def unique[F[_]: Sync, A](name: String): F[Key[A]] = Sync[F].delay(new Key(name)) + + implicit def provider[F[_]: Sync]: context.Key.Provider[F, Key] = + new context.Key.Provider[F, Key] { + def uniqueKey[A](name: String): F[Key[A]] = unique(name) + } } def wrap(context: JContext): Context = { @@ -69,17 +74,11 @@ object Context { implicit object Ctx extends context.Context[Context] { type Key[A] = Context.Key[A] - type KeyCreationBounds[F[_]] = Sync[F] - type KeyTypeBounds[A] = context.Key.NoBounds[A] def get[A](ctx: Context)(key: Key[A]): Option[A] = ctx.get(key) def updated[A](ctx: Context)(key: Key[A], value: A): Context = ctx.updated(key, value) def root: Context = Context.root - def uniqueKey[F[_]: Sync, A: context.Key.NoBounds]( - name: String - ): F[Key[A]] = - Context.Key.unique(name) } }