Skip to content

Commit

Permalink
syntax and representableK macro adopt.
Browse files Browse the repository at this point in the history
  • Loading branch information
Grryum committed Dec 2, 2023
1 parent c31db63 commit 7223e46
Show file tree
Hide file tree
Showing 30 changed files with 194 additions and 126 deletions.
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ lazy val loggingStr = projectMatrix
.settings(
name := "tofu-logging-structured",
defaultSettings,
scala3MigratedModuleOptions,
libraryDependencies ++= Seq(
catsCore,
circeCore,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ trait Function2K[F[_], G[_], H[_]] {
}

object Function2K {
type HKAny[A] = Any

private[this] val representableAny = new Function2KRepresentable[HKAny, HKAny]

implicit def representableK[F[_], G[_]]: RepresentableK[({ type L[x[_]] = Function2K[F, G, x] })#L] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ package object higherKind {
type Pre[F[_], A] = Pre.T[F, A]

type UnitK[A] = Unit

type HKAny[_] = Any
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tofu.logging

import tofu.higherKind.derived.HigherKindedMacros

trait LoggingMidMacroInstances {
def instance[U[_[_]]]: U[LoggingMid] = macro HigherKindedMacros.factorizeThis[U]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package tofu.logging

import tofu.higherKind.RepresentableK
import tofu.higherKind

import scala.annotation.nowarn

trait LoggingRepresentableKInstances {
@nowarn("cat=w-flag-self-implicit")
implicit val loggingRepresentable: RepresentableK[Logging] = higherKind.derived.genRepresentableK[Logging]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package tofu
package logging

import tofu.higherKind.RepresentableK

trait ServiceLoggingRepresentableKInstances {

private[this] val representableAny: RepresentableK[({ type L[x[_]] = ServiceLogging[x, Any] })#L] =
higherKind.derived.genRepresentableK[({ type L[x[_]] = ServiceLogging[x, Any] })#L]

final implicit def serviceLoggingRepresentable[Svc]: RepresentableK[({ type L[x[_]] = ServiceLogging[x, Svc] })#L] =
representableAny.asInstanceOf[RepresentableK[({ type L[x[_]] = ServiceLogging[x, Svc] })#L]]

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package tofu.logging.impl

import cats.{FlatMap, Id}
import tofu.lift.Lift
import tofu.logging.{Logging, Logs}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package tofu.logging.internal

import tofu.higherKind
import tofu.higherKind.RepresentableK
import tofu.logging.Logs
import cats.Id

trait LogsRepresentableKInstances {
private[this] val logs1RepresentableAny: RepresentableK[({ type L[x[_]] = Logs[x, Any] })#L] =
higherKind.derived.genRepresentableK[({ type L[x[_]] = Logs[x, Any] })#L]

implicit def logs1Representable[Y[_]]: RepresentableK[({ type L[x[_]] = Logs[x, Y] })#L] =
logs1RepresentableAny.asInstanceOf[RepresentableK[({ type L[x[_]] = Logs[x, Y] })#L]]

implicit val logs2UniversalRepresentable: RepresentableK[({ type L[x[_]] = Logs[Id, x] })#L] =
higherKind.derived.genRepresentableK[({ type L[x[_]] = Logs[Id, x] })#L]

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package tofu.logging

trait LoggingMidMacroInstances {
// TODO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package tofu.logging

trait LoggingRepresentableKInstances {
// TODO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package tofu.logging

trait ServiceLoggingRepresentableKInstances {
// TODO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package tofu.logging.impl

import cats.{FlatMap, Id}
import tofu.lift.Lift
import tofu.logging.{Logging, Logs}

import scala.reflect.ClassTag

class UniversalEmbedLogs[I[_], F[_]: FlatMap](underlying: Logs[I, F])(implicit lift: Lift[I, F]) extends Logs.Universal[F] {
// TODO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package tofu.logging.internal

trait LogsRepresentableKInstances {
// TODO
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package tofu.logging.location

trait LocationMacroInstances:
// TODO
implicit def location: Location = ???
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class LogAnnotation[A](val name: String, valueLoggable: Loggable[A]) {
override def hashCode: Int = name.hashCode

override def equals(other: Any): Boolean = other match {
case other: LogAnnotation[_] => name == other.name
case other: LogAnnotation[?] => name == other.name
case _ => false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import cats.kernel.Monoid
import cats.{Applicative, Apply, FlatMap, Id}
import org.slf4j.Marker
import tofu.compat.unused
import tofu.higherKind.{Function2K, RepresentableK}
import tofu.higherKind.Function2K
import tofu.logging.Logging.{Debug, Error, Info, Level, Trace, Warn}
import tofu.logging.impl.{EmbedLogging, UniversalContextLogs, UniversalLogging}
import tofu.syntax.monadic._
import tofu.syntax.monoidalK._
import tofu.{Delay, Init, WithContext, higherKind}
import tofu.{Delay, Init, WithContext}

import scala.reflect.ClassTag
import scala.annotation.nowarn

/** Typeclass equivalent of Logger. May contain specified some Logger instance or try to read it from the context
*/
Expand Down Expand Up @@ -79,18 +78,12 @@ trait ServiceLogging[F[_], Service] extends LoggingBase[F] {
final def to[Svc2]: ServiceLogging[F, Svc2] = this.asInstanceOf[ServiceLogging[F, Svc2]]
}

object ServiceLogging {
private[this] val representableAny: RepresentableK[({ type L[x[_]] = ServiceLogging[x, Any] })#L] =
higherKind.derived.genRepresentableK[({ type L[x[_]] = ServiceLogging[x, Any] })#L]

object ServiceLogging extends ServiceLoggingRepresentableKInstances {
implicit def initByLogs[I[_], F[_], Svc: ClassTag](implicit logs: Logs[I, F]): Init[I, ServiceLogging[F, Svc]] =
new Init[I, ServiceLogging[F, Svc]] {
def init: I[ServiceLogging[F, Svc]] = logs.service[Svc]
}

final implicit def serviceLoggingRepresentable[Svc]: RepresentableK[({ type L[x[_]] = ServiceLogging[x, Svc] })#L] =
representableAny.asInstanceOf[RepresentableK[({ type L[x[_]] = ServiceLogging[x, Svc] })#L]]

final implicit def byUniversal[F[_], Svc: ClassTag](implicit unilogs: Logging.Make[F]): ServiceLogging[F, Svc] =
unilogs.service[Svc]
}
Expand All @@ -105,7 +98,7 @@ trait Logging[F[_]] extends ServiceLogging[F, Nothing] {
def asLogging: Logging[F] = this
}

object Logging {
object Logging extends LoggingRepresentableKInstances {

type Make[F[_]] = Logs[Id, F]

Expand Down Expand Up @@ -134,8 +127,8 @@ object Logging {

type ForService[F[_], Svc] <: Logging[F]

type Safe[F[_, _]] = Logging[F[Nothing, *]]
type SafeBase[F[_, _]] = LoggingBase[F[Nothing, *]]
type Safe[F[_, _]] = Logging[F[Nothing, _]]
type SafeBase[F[_, _]] = LoggingBase[F[Nothing, _]]

def apply[F[_]](implicit logging: Logging[F]): Logging[F] = logging

Expand All @@ -144,13 +137,10 @@ object Logging {

/** having two logging implementation call `first` after `second` */
def combine[F[_]: Apply](first: Logging[F], second: Logging[F]): Logging[F] =
first.zipWithK(second)(Function2K[F, F, F](_ *> _))
first.zipWithK[F, F](second)(Function2K[F, F, F](_ *> _))

def flatten[F[_]: FlatMap](underlying: F[Logging[F]]): Logging[F] = new EmbedLogging[F](underlying)

@nowarn("cat=w-flag-self-implicit")
implicit val loggingRepresentable: RepresentableK[Logging] = higherKind.derived.genRepresentableK[Logging]

implicit def loggingMonoid[F[_]: Applicative]: Monoid[Logging[F]] = new Monoid[Logging[F]] {
val empty: Logging[F] = Logging.empty[F]
def combine(x: Logging[F], y: Logging[F]): Logging[F] = Logging.combine(x, y)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import cats.{Functor, Id, Monad}
import tofu.higherKind.{Function2K, Mid, MonoidalK}
import tofu.syntax.monadic._
import tofu.syntax.monoidalK._
import tofu.higherKind.HKAny

/** Mix-in trait that supposed to be extended by companion of service
*
* @example
* {{{class FooService[F[_] : FooService.Log] object FooService extends LoggingCompanion[FooService]}}}
*/
trait LoggingCompanion[U[_[_]]] {
type Log[F[_]] = ServiceLogging[F, U[Any]]
type Log[F[_]] = ServiceLogging[F, U[HKAny]]

implicit def toLogMidOps[F[_]](uf: U[F]): LogMidOps[U, F] = new LogMidOps(uf)

Expand All @@ -24,56 +25,56 @@ trait LoggingCompanion[U[_[_]]] {
svc: ClassTag[U[F]],
U: FunctorK[U],
UM: LoggingMid.Of[U]
): U[Mid[F, *]] = Logging.mid.in[U, Id, F]
): U[Mid[F, _]] = Logging.mid.in[U, Id, F]

def logMidNamed[F[_]: Monad](name: String)(implicit
L: Logging.Make[F],
U: FunctorK[U],
UM: LoggingMid.Of[U]
): U[Mid[F, *]] = Logging.mid.named[U, Id, F](name)
): U[Mid[F, _]] = Logging.mid.named[U, Id, F](name)

def logErrMid[F[+_]: Monad, E](implicit
logs: Logging.Make[F],
UCls: ClassTag[U[F]],
lmid: LoggingErrMid.Of[U, E],
errs: Errors[F, E],
U: FunctorK[U],
): U[Mid[F, *]] = Logging.mid.errIn[U, Id, F, E]
): U[Mid[F, _]] = Logging.mid.errIn[U, Id, F, E]

def logErrMidNamed[F[+_]: Monad, E](name: String)(implicit
logs: Logging.Make[F],
lmid: LoggingErrMid.Of[U, E],
errs: Errors[F, E],
U: FunctorK[U],
): U[Mid[F, *]] = Logging.mid.namedErr[U, Id, F, E](name)
): U[Mid[F, _]] = Logging.mid.namedErr[U, Id, F, E](name)

def logMidIn[I[_]: Functor, F[_]: Monad](implicit
L: Logs[I, F],
svc: ClassTag[U[F]],
U: FunctorK[U],
UM: LoggingMid.Of[U]
): I[U[Mid[F, *]]] = Logging.mid.in[U, I, F]
): I[U[Mid[F, _]]] = Logging.mid.in[U, I, F]

def logMidNamedIn[I[_]: Functor, F[_]: Monad](name: String)(implicit
L: Logs[I, F],
U: FunctorK[U],
UM: LoggingMid.Of[U]
): I[U[Mid[F, *]]] = Logging.mid.named[U, I, F](name)
): I[U[Mid[F, _]]] = Logging.mid.named[U, I, F](name)

def logErrMidIn[I[_]: Functor, F[+_]: Monad, E](implicit
logs: Logs[I, F],
UCls: ClassTag[U[F]],
lmid: LoggingErrMid.Of[U, E],
errs: Errors[F, E],
U: FunctorK[U],
): I[U[Mid[F, *]]] = Logging.mid.errIn[U, I, F, E]
): I[U[Mid[F, _]]] = Logging.mid.errIn[U, I, F, E]

def logErrMidNamedIn[I[_]: Functor, F[+_]: Monad, E](name: String)(implicit
logs: Logs[I, F],
lmid: LoggingErrMid.Of[U, E],
errs: Errors[F, E],
U: FunctorK[U],
): I[U[Mid[F, *]]] = Logging.mid.namedErr[U, I, F, E](name)
): I[U[Mid[F, _]]] = Logging.mid.namedErr[U, I, F, E](name)

}

Expand All @@ -86,7 +87,7 @@ class LogMidOps[U[f[_]], F[_]](private val uf: U[F]) extends AnyVal {
F: Monad[F]
): U[F] = {
implicit val FL: Logging[F] = L.forService[U[F]]
UL.zipWithK(uf)(Function2K.apply((l, fx) => l.around(fx)))
UL.zipWithK(uf)(Function2K.apply[LoggingMid, F]((l, fx) => l.around(fx)))
}

def attachLogsNamed(name: String)(implicit
Expand All @@ -96,7 +97,7 @@ class LogMidOps[U[f[_]], F[_]](private val uf: U[F]) extends AnyVal {
F: Monad[F]
): U[F] = {
implicit val FL: Logging[F] = L.byName(name)
UL.zipWithK(uf)(Function2K.apply((l, fx) => l.around(fx)))
UL.zipWithK(uf)(Function2K.apply[LoggingMid, F]((l, fx) => l.around(fx)))
}

def attachLogsIn[I[_]](implicit
Expand All @@ -107,7 +108,7 @@ class LogMidOps[U[f[_]], F[_]](private val uf: U[F]) extends AnyVal {
U: MonoidalK[U],
F: Monad[F]
): I[U[F]] = L.forService[U[F]].map { implicit logging =>
UL.zipWithK(uf)(Function2K.apply((l, fx) => l.around(fx)))
UL.zipWithK(uf)(Function2K.apply[LoggingMid, F]((l, fx) => l.around(fx)))
}

def attachLogsNamedIn[I[_]](name: String)(implicit
Expand All @@ -117,52 +118,52 @@ class LogMidOps[U[f[_]], F[_]](private val uf: U[F]) extends AnyVal {
U: MonoidalK[U],
F: Monad[F]
): I[U[F]] = L.byName(name).map { implicit logging =>
UL.zipWithK(uf)(Function2K.apply((l, fx) => l.around(fx)))
UL.zipWithK(uf)(Function2K.apply[LoggingMid, F]((l, fx) => l.around(fx)))
}

def attachErrLogs[E](implicit
UL: U[LoggingErrMid[E, *]],
UL: U[LoggingErrMid[E, _]],
cls: ClassTag[U[F]],
L: Logging.Make[F],
U: MonoidalK[U],
F: Monad[F],
FE: Errors[F, E],
): U[F] = {
implicit val FL: Logging[F] = L.forService[U[F]]
UL.zipWithK(uf)(Function2K.apply((l, fx) => l.aroundErr(fx)))
UL.zipWithK(uf)(Function2K.apply[LoggingErrMid[E, _], F]((l, fx) => l.aroundErr(fx)))
}

def attachErrLogsNamed[E](name: String)(implicit
UL: U[LoggingErrMid[E, *]],
UL: U[LoggingErrMid[E, _]],
L: Logging.Make[F],
U: MonoidalK[U],
F: Monad[F],
FE: Errors[F, E],
): U[F] = {
implicit val FL: Logging[F] = L.byName(name)
UL.zipWithK(uf)(Function2K.apply((l, fx) => l.aroundErr(fx)))
UL.zipWithK(uf)(Function2K.apply[LoggingErrMid[E, _], F]((l, fx) => l.aroundErr(fx)))
}

def attachErrLogsIn[I[_], E](implicit
I: Functor[I],
UL: U[LoggingErrMid[E, *]],
UL: U[LoggingErrMid[E, _]],
cls: ClassTag[U[F]],
L: Logs[I, F],
U: MonoidalK[U],
F: Monad[F],
FE: Errors[F, E],
): I[U[F]] = L.forService[U[F]].map { implicit logging =>
UL.zipWithK(uf)(Function2K.apply((l, fx) => l.aroundErr(fx)))
UL.zipWithK(uf)(Function2K.apply[LoggingErrMid[E, _], F]((l, fx) => l.aroundErr(fx)))
}

def attachErrLogsNamedIn[I[_], E](name: String)(implicit
I: Functor[I],
UL: U[LoggingErrMid[E, *]],
UL: U[LoggingErrMid[E, _]],
L: Logs[I, F],
U: MonoidalK[U],
F: Monad[F],
FE: Errors[F, E],
): I[U[F]] = L.byName(name).map { implicit logging =>
UL.zipWithK(uf)(Function2K.apply((l, fx) => l.aroundErr(fx)))
UL.zipWithK(uf)(Function2K.apply[LoggingErrMid[E, _], F]((l, fx) => l.aroundErr(fx)))
}
}
Loading

0 comments on commit 7223e46

Please sign in to comment.