dave08
05/16/2024, 11:15 AMdave08
05/16/2024, 11:16 AMinline fun <reified T : Any> KtorCtx.ensureParameter(name: String): Either<ResponseError, T> = either {
    val value = call.parameters[name]
    ensureNotNull(value) { ResponseError.MissingQueryParameter(name) }
    when(T::class) {
        String::class ->
            value as T
        Int::class ->
            ensureNotNull(value.toIntOrNull()) { ResponseError.QueryParameterCastNotPossible(name, T::class.qualifiedName ?: "") } as T
        else ->
            raise(ResponseError.QueryParameterCastNotPossible(name, T::class.qualifiedName ?: ""))
    }
}
inline fun <reified T : Any, R : Any> KtorCtx.ensureParameter(
    name: String, factory: (T) -> Either<Error, R>
): Either<ResponseError, R> = ensureParameter<T>(name).flatMap { value ->
    factory(value).mapLeft { ResponseError.InvalidParameter("$name: $value") }
}
inline fun <reified T : Any, R : Any> KtorCtx.ensureParameter(
    name: String, factory: (T) -> R
): Either<ResponseError , R> = either { 
    ensureParameter<T>(name).let { value ->
        withError({ ResponseError.InvalidParameter("$name: $value") }) {
            factory(value.bind())
        }
    }
}dave08
05/16/2024, 11:19 AMval param1 = ensureParameter("param1", ParamType::invoke) // Invoke returns Either<SomeDomainError, ...>
val param2 = ensureParameter("param2", ::ParamType2)Alejandro Serrano.Mena
05/16/2024, 11:43 AMletflatMapAlejandro Serrano.Mena
05/16/2024, 11:44 AMinline fun <reified T : Any, R : Any> KtorCtx.ensureParameter(
    name: String, factory: (T) -> R
): Either<ResponseError , R> = either { 
  val param = ensureParameter<T>(name).bind()
  withError({ ResponseError.InvalidParameter("$name: $value") }) {
    factory(param)
  }
}dave08
05/16/2024, 11:47 AM@JvmName("ensureParameter_either")
inline fun <reified T : Any, R : Any> KtorCtx.ensureParameter(
    name: String, factory: (T) -> Either<Error, R>
): Either<ResponseError, R> = either { 
    factory(ensureParameter<T>(name).bind()).mapLeft { ResponseError.InvalidParameter("$name: $value") }.bind()
}dave08
05/16/2024, 11:48 AMAlejandro Serrano.Mena
05/16/2024, 11:50 AMeither { 
    val param = ensureParameter<T>(name).bind()
    withError({ ResponseError.InvalidParameter("$name: $value")  }) {
      factory(param).bind()
    }
}withErrormapLeftdave08
05/16/2024, 11:51 AMAlejandro Serrano.Mena
05/16/2024, 11:51 AMbinddave08
05/16/2024, 11:54 AMdave08
05/16/2024, 11:55 AMAlejandro Serrano.Mena
05/16/2024, 11:55 AMAlejandro Serrano.Mena
05/16/2024, 11:56 AMIt's been a while I've been using Arrow, but I never really got this point clear when to use what... there's a bunch of ways to do the same thing 🤯yep, this is one rough problem to solve. On the one hand, we want to give people who are used to Either from other ecosystems the tools they're used to work with. On the other hand, we want to have a powerful Raise DSL because we think it embodies the Kotlin-idiomatic approach better. So we end up with two ways to do the same.
Emil Kantis
05/16/2024, 11:56 AMdave08
05/16/2024, 12:01 PMwithErrormapLeftLarry Garfield
05/16/2024, 1:29 PMAlejandro Serrano.Mena
05/16/2024, 1:34 PMLarry Garfield
05/16/2024, 1:38 PMdave08
05/16/2024, 1:42 PMdave08
05/16/2024, 1:42 PMdave08
05/16/2024, 1:43 PMdave08
05/16/2024, 1:44 PMAlejandro Serrano.Mena
05/16/2024, 1:44 PMAlejandro Serrano.Mena
05/16/2024, 1:45 PMLarry Garfield
05/16/2024, 1:46 PMdave08
05/16/2024, 1:47 PMLarry Garfield
05/16/2024, 1:47 PMdave08
05/16/2024, 1:53 PMLarry Garfield
05/16/2024, 1:54 PMLarry Garfield
05/16/2024, 1:54 PMdave08
05/16/2024, 1:57 PMLarry Garfield
05/16/2024, 2:03 PMAlejandro Serrano.Mena
05/16/2024, 8:04 PMEitherLarry Garfield
05/16/2024, 8:04 PMNick
05/20/2024, 7:56 PMEitherRaiseEitherRaise