@@ -7,6 +7,8 @@ import cats.implicits._
77import io .prometheus .client .{Histogram => JHistogram }
88import scala .concurrent .duration ._
99import shapeless ._
10+ import io .chrisdavenport .epimetheus .Histogram .UnlabelledHistogramImpl
11+ import io .chrisdavenport .epimetheus .Histogram .MapKUnlabelledHistogram
1012
1113/**
1214 * Histogram metric, to track distributions of events.
@@ -26,6 +28,8 @@ sealed abstract class Histogram[F[_]]{
2628 */
2729 def observe (d : Double ): F [Unit ]
2830
31+ def mapK [G [_]](fk : F ~> G ): Histogram [G ] = new Histogram .MapKHistogram [F , G ](this , fk)
32+
2933}
3034
3135/**
@@ -203,7 +207,7 @@ object Histogram {
203207 .buckets(buckets:_* )
204208 )
205209 out <- Sync [F ].delay(c.register(CollectorRegistry .Unsafe .asJava(cr)))
206- } yield new UnlabelledHistogram [F , A ](out, f.andThen(_.unsized))
210+ } yield new UnlabelledHistogramImpl [F , A ](out, f.andThen(_.unsized))
207211
208212 def labelledLinearBuckets [F [_]: Sync , A , N <: Nat ](
209213 cr : CollectorRegistry [F ],
@@ -223,7 +227,7 @@ object Histogram {
223227 .linearBuckets(start, factor, count)
224228 )
225229 out <- Sync [F ].delay(c.register(CollectorRegistry .Unsafe .asJava(cr)))
226- } yield new UnlabelledHistogram [F , A ](out, f.andThen(_.unsized))
230+ } yield new UnlabelledHistogramImpl [F , A ](out, f.andThen(_.unsized))
227231
228232 def labelledExponentialBuckets [F [_]: Sync , A , N <: Nat ](
229233 cr : CollectorRegistry [F ],
@@ -243,7 +247,7 @@ object Histogram {
243247 .exponentialBuckets(start, factor, count)
244248 )
245249 out <- Sync [F ].delay(c.register(CollectorRegistry .Unsafe .asJava(cr)))
246- } yield new UnlabelledHistogram [F , A ](out, f.andThen(_.unsized))
250+ } yield new UnlabelledHistogramImpl [F , A ](out, f.andThen(_.unsized))
247251
248252 private final class NoLabelsHistogram [F [_]: Sync ] private [Histogram ] (
249253 private [Histogram ] val underlying : JHistogram
@@ -258,26 +262,42 @@ object Histogram {
258262 def observe (d : Double ): F [Unit ] = Sync [F ].delay(underlying.observe(d))
259263 }
260264
265+ private final class MapKHistogram [F [_], G [_]](private [Histogram ] val base : Histogram [F ], fk : F ~> G ) extends Histogram [G ]{
266+ def observe (d : Double ): G [Unit ] = fk(base.observe(d))
267+ }
268+
261269 /**
262270 * Generic UnlabelledHistorgram
263271 *
264272 * It is necessary to apply a value of type `A` to this
265273 * histogram to be able to take any measurements.
266274 */
267- final class UnlabelledHistogram [F [_]: Sync , A ] private [Histogram ] (
275+ sealed trait UnlabelledHistogram [F [_], A ]{
276+ def label (a : A ): Histogram [F ]
277+ def mapK [G [_]](fk : F ~> G ): UnlabelledHistogram [G , A ] = new MapKUnlabelledHistogram [F , G , A ](this , fk)
278+ }
279+
280+ final private class UnlabelledHistogramImpl [F [_]: Sync , A ] private [Histogram ] (
268281 private [Histogram ] val underlying : JHistogram ,
269282 private val f : A => IndexedSeq [String ]
270- ) {
283+ ) extends UnlabelledHistogram [ F , A ] {
271284 def label (a : A ): Histogram [F ] =
272285 new LabelledHistogram [F ](underlying.labels(f(a):_* ))
273286 }
274287
288+ final private class MapKUnlabelledHistogram [F [_], G [_], A ](private [Histogram ] val base : UnlabelledHistogram [F , A ], fk : F ~> G ) extends UnlabelledHistogram [G , A ]{
289+ def label (a : A ): Histogram [G ] = base.label(a).mapK(fk)
290+ }
291+
275292 object Unsafe {
276- def asJavaUnlabelled [F [_], A ](h : UnlabelledHistogram [F , A ]): JHistogram =
277- h.underlying
293+ def asJavaUnlabelled [F [_], A ](h : UnlabelledHistogram [F , A ]): JHistogram = h match {
294+ case h : UnlabelledHistogramImpl [_, _] => h.underlying
295+ case h : MapKUnlabelledHistogram [_, _, _] => asJavaUnlabelled(h.base)
296+ }
278297 def asJava [F [_]: ApplicativeError [? [_], Throwable ]](c : Histogram [F ]): F [JHistogram ] = c match {
279298 case _ : LabelledHistogram [F ] => ApplicativeError [F , Throwable ].raiseError(new IllegalArgumentException (" Cannot Get Underlying Parent with Labels Applied" ))
280299 case n : NoLabelsHistogram [F ] => n.underlying.pure[F ]
300+ case h : MapKHistogram [_, _] => asJava(h.base)
281301 }
282302 }
283303
0 commit comments