@@ -8,8 +8,7 @@
Loading
8 8
9 9
import cats.{Apply, FlatMap, NonEmptyParallel, Show}
10 10
import cats.arrow.FunctionK
11 -
import cats.effect.{Async, Blocker, ContextShift, Effect, Resource}
12 -
import cats.effect.implicits._
11 +
import cats.effect.kernel.{Async, Resource}
13 12
import ciris.ConfigEntry.{Default, Failed, Loaded}
14 13
15 14
/**
@@ -61,14 +60,14 @@
Loading
61 60
  * config: ciris.ConfigValue[Config] = ciris.ConfigValue$$$$anon$$3@565e528c
62 61
  * }}}
63 62
  */
64 -
sealed abstract class ConfigValue[A] {
65 -
  private[this] final val self: ConfigValue[A] = this
63 +
sealed abstract class ConfigValue[+F[_], A] {
64 +
  private[this] final val self: ConfigValue[F, A] = this
66 65
67 66
  /**
68 67
    * Returns a new [[ConfigValue]] which attempts to decode the
69 68
    * value to the specified type.
70 69
    */
71 -
  final def as[B](implicit decoder: ConfigDecoder[A, B]): ConfigValue[B] =
70 +
  final def as[B](implicit decoder: ConfigDecoder[A, B]): ConfigValue[F, B] =
72 71
    transform {
73 72
      case Default(error, a) =>
74 73
        decoder.decode(None, a()) match {
@@ -96,12 +95,9 @@
Loading
96 95
    * If this behaviour is not desired, we can instead use
97 96
    * [[ConfigValue#resource]] to return a `Resource`.
98 97
    */
99 -
  final def attempt[F[_]](
100 -
    implicit F: Async[F],
101 -
    context: ContextShift[F]
102 -
  ): F[Either[ConfigError, A]] =
103 -
    to[F].use { result =>
104 -
      F.pure(result match {
98 +
  final def attempt[G[x] >: F[x]](implicit G: Async[G]): G[Either[ConfigError, A]] =
99 +
    to[G].use { result =>
100 +
      G.pure(result match {
105 101
        case Default(_, a)   => Right(a())
106 102
        case Failed(error)   => Left(error)
107 103
        case Loaded(_, _, a) => Right(a)
@@ -119,7 +115,7 @@
Loading
119 115
    *
120 116
    * Using `.default(a)` is equivalent to using `.or(default(a))`.
121 117
    */
122 -
  final def default(value: => A): ConfigValue[A] =
118 +
  final def default(value: => A): ConfigValue[F, A] =
123 119
    transform {
124 120
      case Default(error, _)                => Default(error, () => value)
125 121
      case Failed(error) if error.isMissing => Default(error, () => value)
@@ -131,38 +127,32 @@
Loading
131 127
    * Returns a new [[ConfigValue]] which applies the
132 128
    * specified effectful function on the value.
133 129
    */
134 -
  final def evalMap[F[_], B](f: A => F[B])(implicit F: Effect[F]): ConfigValue[B] =
135 -
    new ConfigValue[B] {
136 -
      override final def to[G[_]](
137 -
        implicit G: Async[G],
138 -
        context: ContextShift[G]
139 -
      ): Resource[G, ConfigEntry[B]] =
140 -
        self.to[G].evalMap(_.traverse(f).toIO.to[G])
130 +
  final def evalMap[G[x] >: F[x], B](f: A => G[B]): ConfigValue[G, B] =
131 +
    new ConfigValue[G, B] {
132 +
      override final def to[H[x] >: G[x]](implicit H: Async[H]): Resource[H, ConfigEntry[B]] =
133 +
        self.to[H].evalMap(_.traverse(f)(H.asInstanceOf[Async[G]]))
141 134
    }
142 135
143 136
  /**
144 137
    * Returns a new [[ConfigValue]] which loads the specified
145 138
    * configuration using the value.
146 139
    */
147 -
  final def flatMap[B](f: A => ConfigValue[B]): ConfigValue[B] =
148 -
    new ConfigValue[B] {
149 -
      override final def to[F[_]](
150 -
        implicit F: Async[F],
151 -
        context: ContextShift[F]
152 -
      ): Resource[F, ConfigEntry[B]] =
153 -
        self.to[F].flatMap {
140 +
  final def flatMap[G[x] >: F[x], B](f: A => ConfigValue[G, B]): ConfigValue[G, B] =
141 +
    new ConfigValue[G, B] {
142 +
      override final def to[H[x] >: G[x]](implicit H: Async[H]): Resource[H, ConfigEntry[B]] =
143 +
        self.to[H].flatMap {
154 144
          case Default(_, a) =>
155 -
            f(a()).to[F].map {
145 +
            f(a()).to[H].map {
156 146
              case Default(_, b)      => ConfigEntry.default(b())
157 147
              case failed @ Failed(_) => failed
158 148
              case Loaded(_, _, b)    => ConfigEntry.loaded(None, b)
159 149
            }
160 150
161 151
          case failed @ Failed(_) =>
162 -
            Resource.liftF(F.pure(failed))
152 +
            Resource.liftF(H.pure(failed))
163 153
164 154
          case Loaded(_, _, a) =>
165 -
            f(a).to[F].map {
155 +
            f(a).to[H].map {
166 156
              case Default(_, b)   => ConfigEntry.loaded(None, b())
167 157
              case Failed(e2)      => ConfigEntry.failed(ConfigError.Loaded.and(e2))
168 158
              case Loaded(_, _, b) => ConfigEntry.loaded(None, b)
@@ -180,21 +170,18 @@
Loading
180 170
    * If this behaviour is not desired, we can instead use
181 171
    * [[ConfigValue#resource]] to return a `Resource`.
182 172
    */
183 -
  final def load[F[_]](
184 -
    implicit F: Async[F],
185 -
    context: ContextShift[F]
186 -
  ): F[A] =
187 -
    to[F].use {
188 -
      case Default(_, a)   => F.pure(a())
189 -
      case Failed(error)   => F.raiseError(error.throwable)
190 -
      case Loaded(_, _, a) => F.pure(a)
173 +
  final def load[G[x] >: F[x]](implicit G: Async[G]): G[A] =
174 +
    to[G].use {
175 +
      case Default(_, a)   => G.pure(a())
176 +
      case Failed(error)   => G.raiseError(error.throwable)
177 +
      case Loaded(_, _, a) => G.pure(a)
191 178
    }
192 179
193 180
  /**
194 181
    * Returns a new [[ConfigValue]] which applies the
195 182
    * specified function on the value.
196 183
    */
197 -
  final def map[B](f: A => B): ConfigValue[B] =
184 +
  final def map[B](f: A => B): ConfigValue[F, B] =
198 185
    transform(_.map(f))
199 186
200 187
  /**
@@ -203,7 +190,7 @@
Loading
203 190
    *
204 191
    * Using `.option` is equivalent to using `.map(_.some).default(None)`.
205 192
    */
206 -
  final def option: ConfigValue[Option[A]] =
193 +
  final def option: ConfigValue[F, Option[A]] =
207 194
    transform {
208 195
      case Default(error, _)                => Default(error, () => None)
209 196
      case Failed(error) if error.isMissing => Default(error, () => None)
@@ -222,15 +209,12 @@
Loading
222 209
    * defaults. Errors from both the value and the
223 210
    * specified configuration are accumulated.
224 211
    */
225 -
  final def or(value: => ConfigValue[A]): ConfigValue[A] =
226 -
    new ConfigValue[A] {
227 -
      override final def to[F[_]](
228 -
        implicit F: Async[F],
229 -
        context: ContextShift[F]
230 -
      ): Resource[F, ConfigEntry[A]] =
231 -
        self.to[F].flatMap {
212 +
  final def or[G[x] >: F[x]](value: => ConfigValue[G, A]): ConfigValue[G, A] =
213 +
    new ConfigValue[G, A] {
214 +
      override final def to[H[x] >: G[x]](implicit H: Async[H]): Resource[H, ConfigEntry[A]] =
215 +
        self.to[H].flatMap {
232 216
          case Default(error, a) =>
233 -
            value.to[F].map {
217 +
            value.to[H].map {
234 218
              case Failed(nextError) if nextError.isMissing => Default(error.or(nextError), a)
235 219
              case Failed(nextError)                        => Failed(error.or(nextError))
236 220
              case Default(nextError, b)                    => Default(error.or(nextError), b)
@@ -238,28 +222,20 @@
Loading
238 222
            }
239 223
240 224
          case Failed(error) if error.isMissing =>
241 -
            value.to[F].map {
225 +
            value.to[H].map {
242 226
              case Failed(nextError)         => Failed(error.or(nextError))
243 227
              case Default(nextError, b)     => Default(error.or(nextError), b)
244 228
              case Loaded(nextError, key, b) => Loaded(error.or(nextError), key, b)
245 229
            }
246 230
247 231
          case failed @ Failed(_) =>
248 -
            Resource.liftF(F.pure(failed))
232 +
            Resource.liftF(H.pure(failed))
249 233
250 234
          case loaded @ Loaded(_, _, _) =>
251 -
            Resource.liftF(F.pure(loaded))
235 +
            Resource.liftF(H.pure(loaded))
252 236
        }
253 237
    }
254 238
255 -
  /**
256 -
    * Returns a new [[ConfigValue]] which loads the specified
257 -
    * configuration using the value.
258 -
    */
259 -
  @deprecated("Use flatMap instead", "1.2.1")
260 -
  final def parFlatMap[B](f: A => ConfigValue[B]): ConfigValue[B] =
261 -
    flatMap(f)
262 -
263 239
  /**
264 240
    * Returns a new [[ConfigValue]] with sensitive
265 241
    * details redacted from error messages.
@@ -268,21 +244,18 @@
Loading
268 244
    * `.secret.map(_.value)`, except without
269 245
    * requiring a `Show` instance.
270 246
    */
271 -
  final def redacted: ConfigValue[A] =
247 +
  final def redacted: ConfigValue[F, A] =
272 248
    transform(_.mapError(_.redacted))
273 249
274 250
  /**
275 251
    * Returns a `Resource` with the specified effect
276 252
    * type which loads the configuration value.
277 253
    */
278 -
  final def resource[F[_]](
279 -
    implicit F: Async[F],
280 -
    context: ContextShift[F]
281 -
  ): Resource[F, A] =
282 -
    to[F].evalMap[F, A] {
283 -
      case Default(_, a)   => F.pure(a())
284 -
      case Failed(error)   => F.raiseError(error.throwable)
285 -
      case Loaded(_, _, a) => F.pure(a)
254 +
  final def resource[G[x] >: F[x]](implicit G: Async[G]): Resource[G, A] =
255 +
    to[G].evalMap[G, A] {
256 +
      case Default(_, a)   => G.pure(a())
257 +
      case Failed(error)   => G.raiseError(error.throwable)
258 +
      case Loaded(_, _, a) => G.pure(a)
286 259
    }
287 260
288 261
  /**
@@ -296,27 +269,21 @@
Loading
296 269
    * Using `.secret` is equivalent to using
297 270
    * `.redacted.map(Secret(_))`.
298 271
    */
299 -
  final def secret(implicit show: Show[A]): ConfigValue[Secret[A]] =
272 +
  final def secret(implicit show: Show[A]): ConfigValue[F, Secret[A]] =
300 273
    transform {
301 274
      case Default(error, a)     => Default(error.redacted, () => Secret(a()))
302 275
      case Failed(error)         => Failed(error.redacted)
303 276
      case Loaded(error, key, a) => Loaded(error.redacted, key, Secret(a))
304 277
    }
305 278
306 -
  private[ciris] def to[F[_]](
307 -
    implicit F: Async[F],
308 -
    context: ContextShift[F]
309 -
  ): Resource[F, ConfigEntry[A]]
279 +
  private[ciris] def to[G[x] >: F[x]](implicit G: Async[G]): Resource[G, ConfigEntry[A]]
310 280
311 281
  private[ciris] final def transform[B](
312 282
    f: ConfigEntry[A] => ConfigEntry[B]
313 -
  ): ConfigValue[B] =
314 -
    new ConfigValue[B] {
315 -
      override final def to[F[_]](
316 -
        implicit F: Async[F],
317 -
        context: ContextShift[F]
318 -
      ): Resource[F, ConfigEntry[B]] =
319 -
        self.to[F].map(f)
283 +
  ): ConfigValue[F, B] =
284 +
    new ConfigValue[F, B] {
285 +
      override final def to[G[x] >: F[x]](implicit G: Async[G]): Resource[G, ConfigEntry[B]] =
286 +
        self.to[G].map(f)
320 287
    }
321 288
}
322 289
@@ -338,32 +305,24 @@
Loading
338 305
    *
339 306
    * @group Create
340 307
    */
341 -
  final def async[A](k: (Either[Throwable, ConfigValue[A]] => Unit) => Unit): ConfigValue[A] =
342 -
    new ConfigValue[A] {
343 -
      override final def to[F[_]](
344 -
        implicit F: Async[F],
345 -
        context: ContextShift[F]
346 -
      ): Resource[F, ConfigEntry[A]] =
347 -
        Resource.liftF(F.async(k)).flatMap(_.to[F])
308 +
  final def async[F[_], A](
309 +
    k: (Either[Throwable, ConfigValue[F, A]] => Unit) => Unit
310 +
  ): ConfigValue[F, A] =
311 +
    new ConfigValue[F, A] {
312 +
      override final def to[G[x] >: F[x]](implicit G: Async[G]): Resource[G, ConfigEntry[A]] =
313 +
        Resource.liftF(G.async_(k)).flatMap(_.to[G])
348 314
    }
349 315
350 316
  /**
351 317
    * Returns a new [[ConfigValue]] which loads the specified
352 318
    * blocking value.
353 319
    *
354 -
    * Note that if the [[ConfigValue]] contains any resources,
355 -
    * from using [[ConfigValue.resource]], these will be used
356 -
    * (acquired and released) using the specified `Blocker`.
357 -
    *
358 320
    * @group Create
359 321
    */
360 -
  final def blockOn[A](blocker: Blocker)(value: ConfigValue[A]): ConfigValue[A] =
361 -
    new ConfigValue[A] {
362 -
      override final def to[F[_]](
363 -
        implicit F: Async[F],
364 -
        context: ContextShift[F]
365 -
      ): Resource[F, ConfigEntry[A]] =
366 -
        Resource.liftF(context.blockOn(blocker)(value.to[F].use(F.pure)))
322 +
  final def blocking[F[_], A](value: => ConfigValue[F, A]): ConfigValue[F, A] =
323 +
    new ConfigValue[F, A] {
324 +
      override final def to[G[x] >: F[x]](implicit G: Async[G]): Resource[G, ConfigEntry[A]] =
325 +
        Resource.liftF(G.blocking(value)).flatMap(_.to[G])
367 326
    }
368 327
369 328
  /**
@@ -372,7 +331,7 @@
Loading
372 331
    *
373 332
    * @group Create
374 333
    */
375 -
  final def default[A](value: => A): ConfigValue[A] =
334 +
  final def default[F[_], A](value: => A): ConfigValue[F, A] =
376 335
    ConfigValue.pure(ConfigEntry.default(value))
377 336
378 337
  /**
@@ -381,13 +340,10 @@
Loading
381 340
    *
382 341
    * @group Create
383 342
    */
384 -
  final def eval[F[_], A](value: F[ConfigValue[A]])(implicit F: Effect[F]): ConfigValue[A] =
385 -
    new ConfigValue[A] {
386 -
      override final def to[G[_]](
387 -
        implicit G: Async[G],
388 -
        context: ContextShift[G]
389 -
      ): Resource[G, ConfigEntry[A]] =
390 -
        Resource.liftF(value.toIO.to[G]).flatMap(_.to[G])
343 +
  final def eval[F[_], A](value: F[ConfigValue[F, A]]): ConfigValue[F, A] =
344 +
    new ConfigValue[F, A] {
345 +
      override final def to[G[x] >: F[x]](implicit G: Async[G]): Resource[G, ConfigEntry[A]] =
346 +
        Resource.liftF(value)(G.asInstanceOf[Async[F]]).flatMap(_.to[G])
391 347
    }
392 348
393 349
  /**
@@ -396,7 +352,7 @@
Loading
396 352
    *
397 353
    * @group Create
398 354
    */
399 -
  final def failed[A](error: ConfigError): ConfigValue[A] =
355 +
  final def failed[F[_], A](error: ConfigError): ConfigValue[F, A] =
400 356
    ConfigValue.pure(ConfigEntry.failed(error))
401 357
402 358
  /**
@@ -405,7 +361,7 @@
Loading
405 361
    *
406 362
    * @group Create
407 363
    */
408 -
  final def loaded[A](key: ConfigKey, value: A): ConfigValue[A] =
364 +
  final def loaded[F[_], A](key: ConfigKey, value: A): ConfigValue[F, A] =
409 365
    ConfigValue.pure(ConfigEntry.loaded(Some(key), value))
410 366
411 367
  /**
@@ -414,16 +370,13 @@
Loading
414 370
    *
415 371
    * @group Create
416 372
    */
417 -
  final def missing[A](key: ConfigKey): ConfigValue[A] =
373 +
  final def missing[F[_], A](key: ConfigKey): ConfigValue[F, A] =
418 374
    ConfigValue.failed(ConfigError.Missing(key))
419 375
420 -
  private[ciris] final def pure[A](entry: ConfigEntry[A]): ConfigValue[A] =
421 -
    new ConfigValue[A] {
422 -
      override final def to[F[_]](
423 -
        implicit F: Async[F],
424 -
        context: ContextShift[F]
425 -
      ): Resource[F, ConfigEntry[A]] =
426 -
        Resource.liftF(F.pure(entry))
376 +
  private[ciris] final def pure[F[_], A](entry: ConfigEntry[A]): ConfigValue[F, A] =
377 +
    new ConfigValue[F, A] {
378 +
      override final def to[G[x] >: F[x]](implicit G: Async[G]): Resource[G, ConfigEntry[A]] =
379 +
        Resource.liftF(G.pure(entry))
427 380
    }
428 381
429 382
  /**
@@ -432,20 +385,14 @@
Loading
432 385
    * @group Create
433 386
    */
434 387
  final def resource[F[_], A](
435 -
    resource: Resource[F, ConfigValue[A]]
436 -
  )(implicit F: Effect[F]): ConfigValue[A] = {
388 +
    resource: Resource[F, ConfigValue[F, A]]
389 +
  ): ConfigValue[F, A] = {
437 390
    val _resource = resource
438 -
    new ConfigValue[A] {
439 -
      override final def to[G[_]](
440 -
        implicit G: Async[G],
441 -
        context: ContextShift[G]
391 +
    new ConfigValue[F, A] {
392 +
      override final def to[G[x] >: F[x]](
393 +
        implicit G: Async[G]
442 394
      ): Resource[G, ConfigEntry[A]] =
443 -
        _resource
444 -
          .mapK(new FunctionK[F, G] {
445 -
            override final def apply[B](fb: F[B]): G[B] =
446 -
              fb.toIO.to[G]
447 -
          })
448 -
          .flatMap(_.to[G])
395 +
        _resource.flatMap(_.to[G])
449 396
    }
450 397
  }
451 398
@@ -455,35 +402,34 @@
Loading
455 402
    *
456 403
    * @group Create
457 404
    */
458 -
  final def suspend[A](value: => ConfigValue[A]): ConfigValue[A] =
459 -
    new ConfigValue[A] {
460 -
      override final def to[F[_]](
461 -
        implicit F: Async[F],
462 -
        context: ContextShift[F]
463 -
      ): Resource[F, ConfigEntry[A]] =
464 -
        Resource.suspend(F.delay(value.to[F]))
405 +
  final def suspend[F[_], A](value: => ConfigValue[F, A]): ConfigValue[F, A] =
406 +
    new ConfigValue[F, A] {
407 +
      override final def to[G[x] >: F[x]](implicit G: Async[G]): Resource[G, ConfigEntry[A]] =
408 +
        Resource.suspend(G.delay(value.to[G]))
465 409
    }
466 410
467 411
  /**
468 412
    * @group Instances
469 413
    */
470 -
  implicit final val configValueFlatMap: FlatMap[ConfigValue] =
471 -
    new FlatMap[ConfigValue] {
414 +
  implicit final def configValueFlatMap[F[_]]: FlatMap[ConfigValue[F, *]] =
415 +
    new FlatMap[ConfigValue[F, *]] {
472 416
      override final def flatMap[A, B](
473 -
        value: ConfigValue[A]
474 -
      )(f: A => ConfigValue[B]): ConfigValue[B] =
417 +
        value: ConfigValue[F, A]
418 +
      )(f: A => ConfigValue[F, B]): ConfigValue[F, B] =
475 419
        value.flatMap(f)
476 420
477 421
      override final def map[A, B](
478 -
        value: ConfigValue[A]
479 -
      )(f: A => B): ConfigValue[B] =
422 +
        value: ConfigValue[F, A]
423 +
      )(f: A => B): ConfigValue[F, B] =
480 424
        value.map(f)
481 425
482 426
      /**
483 427
        * Note: this is intentionally not stack safe, as the `flatMap`
484 428
        * on `ConfigValue` cannot be expressed in a tail-recursive way.
485 429
        */
486 -
      override final def tailRecM[A, B](a: A)(f: A => ConfigValue[Either[A, B]]): ConfigValue[B] =
430 +
      override final def tailRecM[A, B](
431 +
        a: A
432 +
      )(f: A => ConfigValue[F, Either[A, B]]): ConfigValue[F, B] =
487 433
        f(a).flatMap {
488 434
          case Left(a)  => tailRecM(a)(f)
489 435
          case Right(b) => default(b)
@@ -493,32 +439,29 @@
Loading
493 439
  /**
494 440
    * @group Instances
495 441
    */
496 -
  implicit final val configValueParApply: Apply[Par] =
497 -
    new Apply[Par] {
498 -
      override final def ap[A, B](pab: Par[A => B])(pa: Par[A]): Par[B] =
442 +
  implicit final def configValueParApply[F[_]]: Apply[Par[F, *]] =
443 +
    new Apply[Par[F, *]] {
444 +
      override final def ap[A, B](pab: Par[F, A => B])(pa: Par[F, A]): Par[F, B] =
499 445
        Par {
500 -
          new ConfigValue[B] {
501 -
            override final def to[F[_]](
502 -
              implicit F: Async[F],
503 -
              context: ContextShift[F]
504 -
            ): Resource[F, ConfigEntry[B]] =
505 -
              pab.unwrap.to[F].flatMap {
446 +
          new ConfigValue[F, B] {
447 +
            override final def to[G[x] >: F[x]](implicit G: Async[G]): Resource[G, ConfigEntry[B]] =
448 +
              pab.unwrap.to[G].flatMap {
506 449
                case Default(_, ab) =>
507 -
                  pa.unwrap.to[F].map {
450 +
                  pa.unwrap.to[G].map {
508 451
                    case Default(_, a)      => ConfigEntry.default(ab().apply(a()))
509 452
                    case failed @ Failed(_) => failed
510 453
                    case Loaded(_, _, a)    => ConfigEntry.loaded(None, ab().apply(a))
511 454
                  }
512 455
513 456
                case failed @ Failed(e1) =>
514 -
                  pa.unwrap.to[F].map {
457 +
                  pa.unwrap.to[G].map {
515 458
                    case Default(_, _)   => failed
516 459
                    case Failed(e2)      => ConfigEntry.failed(e1.and(e2))
517 460
                    case Loaded(_, _, _) => ConfigEntry.failed(ConfigError.Loaded.and(e1))
518 461
                  }
519 462
520 463
                case Loaded(_, _, ab) =>
521 -
                  pa.unwrap.to[F].map {
464 +
                  pa.unwrap.to[G].map {
522 465
                    case Default(_, a)   => ConfigEntry.loaded(None, ab(a()))
523 466
                    case Failed(e2)      => ConfigEntry.failed(ConfigError.Loaded.and(e2))
524 467
                    case Loaded(_, _, a) => ConfigEntry.loaded(None, ab(a))
@@ -527,32 +470,33 @@
Loading
527 470
          }
528 471
        }
529 472
530 -
      override final def map[A, B](pa: Par[A])(f: A => B): Par[B] =
473 +
      override final def map[A, B](pa: Par[F, A])(f: A => B): Par[F, B] =
531 474
        Par(pa.unwrap.map(f))
532 475
    }
533 476
534 477
  /**
535 478
    * @group Instances
536 479
    */
537 -
  implicit final val configValueNonEmptyParallel: NonEmptyParallel.Aux[ConfigValue, Par] =
538 -
    new NonEmptyParallel[ConfigValue] {
539 -
      override final type F[A] = Par[A]
480 +
  implicit final def configValueNonEmptyParallel[G[_]]
481 +
    : NonEmptyParallel.Aux[ConfigValue[G, *], Par[G, *]] =
482 +
    new NonEmptyParallel[ConfigValue[G, *]] {
483 +
      override final type F[A] = Par[G, A]
540 484
541 -
      override final val apply: Apply[Par] =
485 +
      override final val apply: Apply[Par[G, *]] =
542 486
        configValueParApply
543 487
544 -
      override final val flatMap: FlatMap[ConfigValue] =
488 +
      override final val flatMap: FlatMap[ConfigValue[G, *]] =
545 489
        configValueFlatMap
546 490
547 -
      override final val parallel: FunctionK[ConfigValue, Par] =
548 -
        new FunctionK[ConfigValue, Par] {
549 -
          override final def apply[A](value: ConfigValue[A]): Par[A] =
491 +
      override final val parallel: FunctionK[ConfigValue[G, *], Par[G, *]] =
492 +
        new FunctionK[ConfigValue[G, *], Par[G, *]] {
493 +
          override final def apply[A](value: ConfigValue[G, A]): Par[G, A] =
550 494
            Par(value)
551 495
        }
552 496
553 -
      override final val sequential: FunctionK[Par, ConfigValue] =
554 -
        new FunctionK[Par, ConfigValue] {
555 -
          override final def apply[A](par: Par[A]): ConfigValue[A] =
497 +
      override final val sequential: FunctionK[Par[G, *], ConfigValue[G, *]] =
498 +
        new FunctionK[Par[G, *], ConfigValue[G, *]] {
499 +
          override final def apply[A](par: Par[G, A]): ConfigValue[G, A] =
556 500
            par.unwrap
557 501
        }
558 502
    }
@@ -562,7 +506,7 @@
Loading
562 506
    *
563 507
    * @group Newtypes
564 508
    */
565 -
  final type Par[A] = Par.Type[A]
509 +
  final type Par[F[_], A] = Par.Type[F, A]
566 510
567 511
  /**
568 512
    * @group Newtypes
@@ -572,23 +516,23 @@
Loading
572 516
573 517
    sealed trait Tag extends Any
574 518
575 -
    type Type[A] <: Base with Tag
519 +
    type Type[F[_], A] <: Base with Tag
576 520
577 521
    /**
578 522
      * Returns a [[Par]] instance for the specified [[ConfigValue]].
579 523
      */
580 -
    final def apply[A](value: ConfigValue[A]): Par[A] =
581 -
      value.asInstanceOf[Par[A]]
524 +
    final def apply[F[_], A](value: ConfigValue[F, A]): Par[F, A] =
525 +
      value.asInstanceOf[Par[F, A]]
582 526
583 -
    implicit final class Ops[A] private[ciris] (
584 -
      private val par: Par[A]
527 +
    implicit final class Ops[F[_], A] private[ciris] (
528 +
      private val par: Par[F, A]
585 529
    ) extends AnyVal {
586 530
587 531
      /**
588 532
        * Returns the underlying [[ConfigValue]] for the instance.
589 533
        */
590 -
      final def unwrap: ConfigValue[A] =
591 -
        par.asInstanceOf[ConfigValue[A]]
534 +
      final def unwrap: ConfigValue[F, A] =
535 +
        par.asInstanceOf[ConfigValue[F, A]]
592 536
    }
593 537
  }
594 538
}

@@ -4,22 +4,26 @@
Loading
4 4
 * SPDX-License-Identifier: MIT
5 5
 */
6 6
7 -
import cats.effect.Blocker
8 7
import java.nio.charset.{Charset, StandardCharsets}
9 8
import java.nio.file.{Files, NoSuchFileException, Path}
10 9
11 10
package object ciris {
12 11
12 +
  /**
13 +
    * Indicates a [[ConfigValue]] works for any effect type.
14 +
    */
15 +
  type Effect[A] <: Nothing
16 +
13 17
  /**
14 18
    * Returns a new [[ConfigValue]] with the specified default value.
15 19
    */
16 -
  final def default[A](value: => A): ConfigValue[A] =
20 +
  final def default[A](value: => A): ConfigValue[Effect, A] =
17 21
    ConfigValue.default(value)
18 22
19 23
  /**
20 24
    * Returns a new [[ConfigValue]] for the specified environment variable.
21 25
    */
22 -
  final def env(name: String): ConfigValue[String] =
26 +
  final def env(name: String): ConfigValue[Effect, String] =
23 27
    ConfigValue.suspend {
24 28
      val key = ConfigKey.env(name)
25 29
      val value = System.getenv(name)
@@ -38,8 +42,8 @@
Loading
38 42
    * The file contents are read synchronously using
39 43
    * the `UTF-8` charset and `Blocker` instance.
40 44
    */
41 -
  final def file(path: Path, blocker: Blocker): ConfigValue[String] =
42 -
    file(path, blocker, StandardCharsets.UTF_8)
45 +
  final def file(path: Path): ConfigValue[Effect, String] =
46 +
    file(path, StandardCharsets.UTF_8)
43 47
44 48
  /**
45 49
    * Returns a new [[ConfigValue]] for the file at the
@@ -48,26 +52,24 @@
Loading
48 52
    * The file contents are read synchronously using
49 53
    * the specified charset and `Blocker` instance.
50 54
    */
51 -
  final def file(path: Path, blocker: Blocker, charset: Charset): ConfigValue[String] =
52 -
    ConfigValue.blockOn(blocker) {
53 -
      ConfigValue.suspend {
54 -
        val key = ConfigKey.file(path, charset)
55 +
  final def file(path: Path, charset: Charset): ConfigValue[Effect, String] =
56 +
    ConfigValue.blocking {
57 +
      val key = ConfigKey.file(path, charset)
55 58
56 -
        try {
57 -
          val bytes = Files.readAllBytes(path)
58 -
          val value = new String(bytes, charset)
59 -
          ConfigValue.loaded(key, value)
60 -
        } catch {
61 -
          case _: NoSuchFileException =>
62 -
            ConfigValue.missing(key)
63 -
        }
59 +
      try {
60 +
        val bytes = Files.readAllBytes(path)
61 +
        val value = new String(bytes, charset)
62 +
        ConfigValue.loaded(key, value)
63 +
      } catch {
64 +
        case _: NoSuchFileException =>
65 +
          ConfigValue.missing(key)
64 66
      }
65 67
    }
66 68
67 69
  /**
68 70
    * Returns a new [[ConfigValue]] for the specified system property.
69 71
    */
70 -
  final def prop(name: String): ConfigValue[String] =
72 +
  final def prop(name: String): ConfigValue[Effect, String] =
71 73
    ConfigValue.suspend {
72 74
      val key = ConfigKey.prop(name)
73 75
Files Coverage
modules 100.00%
Project Totals (15 files) 100.00%

No yaml found.

Create your codecov.yml to customize your Codecov experience

Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading