diff --git a/modules/core/shared/src/main/scala/TraceValue.scala b/modules/core/shared/src/main/scala/TraceValue.scala index 40760c57..55c97226 100644 --- a/modules/core/shared/src/main/scala/TraceValue.scala +++ b/modules/core/shared/src/main/scala/TraceValue.scala @@ -14,11 +14,47 @@ object TraceValue { case class BooleanValue(value: Boolean) extends TraceValue case class NumberValue(value: Number) extends TraceValue - implicit def stringToTraceValue(value: String): TraceValue = StringValue(value) - implicit def boolToTraceValue(value: Boolean): TraceValue = BooleanValue(value) - implicit def intToTraceValue(value: Int): TraceValue = NumberValue(value) - implicit def longToTraceValue(value: Long): TraceValue = NumberValue(value) - implicit def floatToTraceValue(value: Float): TraceValue = NumberValue(value) - implicit def doubleToTraceValue(value: Double): TraceValue = NumberValue(value) + implicit def viaTraceableValue[A: TraceableValue](a: A): TraceValue = + TraceableValue[A].toTraceValue(a) + @deprecated("use toTraceValue", "0.3.0") + def stringToTraceValue(value: String): TraceValue = StringValue(value) + @deprecated("use toTraceValue", "0.3.0") + def boolToTraceValue(value: Boolean): TraceValue = BooleanValue(value) + @deprecated("use toTraceValue", "0.3.0") + def intToTraceValue(value: Int): TraceValue = NumberValue(value) + @deprecated("use toTraceValue", "0.3.0") + def longToTraceValue(value: Long): TraceValue = NumberValue(value) + @deprecated("use toTraceValue", "0.3.0") + def floatToTraceValue(value: Float): TraceValue = NumberValue(value) + @deprecated("use toTraceValue", "0.3.0") + def doubleToTraceValue(value: Double): TraceValue = NumberValue(value) +} + +/** A lawless typeclass responsible for converting a value of the type + * parameter `A` to Natchez's `TraceValue`. + * + * You may want to use this to customize the formatting of a value + * before attaching it to a span, or to support adding tracing as a + * cross-cutting concern using aspect-oriented programming from a + * library such as cats-tagless. + * + * @tparam A The type to be converted to `TraceValue` + */ +trait TraceableValue[A] { outer => + def toTraceValue(a: A): TraceValue + + final def contramap[B](f: B => A): TraceableValue[B] = + (b: B) => outer.toTraceValue(f(b)) +} + +object TraceableValue { + def apply[A: TraceableValue]: TraceableValue[A] = implicitly + + implicit val stringToTraceValue: TraceableValue[String] = TraceValue.StringValue(_) + implicit val booleanToTraceValue: TraceableValue[Boolean] = TraceValue.BooleanValue(_) + implicit val intToTraceValue: TraceableValue[Int] = TraceValue.NumberValue(_) + implicit val longToTraceValue: TraceableValue[Long] = TraceValue.NumberValue(_) + implicit val doubleToTraceValue: TraceableValue[Double] = TraceValue.NumberValue(_) + implicit val floatToTraceValue: TraceableValue[Float] = TraceValue.NumberValue(_) }