Last active
December 3, 2019 22:34
-
-
Save matfournier/c8d46e60f9ab2882ac05eeec47b45869 to your computer and use it in GitHub Desktop.
RefinedCustomValidation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// the type I take in which isn't that useful | |
case class AuthorizeRequest( | |
code: Option[String], | |
token: Option[String], | |
secret: Option[String], | |
verifier: Option[String], | |
redirectUri: String, | |
clientId: String, | |
clientSecret: String | |
) | |
// what I actually want to construct | |
final case class ValidAuthorizeRequest( | |
clientId: String Refined NonEmpty, | |
redirectUri: String Refined Uri, | |
clientSecret: String Refined NonEmpty, | |
code: String Refined NonEmpty | |
) | |
// ideally I would be able to go something like this (assuming request is an instance of AuthorizeRequest | |
// refineV[ValidAuthorizeResult](request.clientId, request.redirectUri, request.secret, request.code)) | |
// attempting to define a Validate instance NOT WORKING | |
implicit val vv:Validate[(String, String, String, Option[String]), ValidAuthorizeRequest] = | |
new Validate[(String, String, String, Option[String]), ValidAuthorizeRequest] { | |
override type R = ??? // not sure if I need to put something here | |
override def showExpr(t: (String, String, String, Option[String])): String = "boo?" // not sure what I need here | |
override def validate(t: (String, String, String, Option[String])): Res = { | |
val (rC, rU, cS, cc) = t | |
val result = for { | |
clientId <- RefType.applyRef[NonEmptyString](rC) | |
redirectUri <- RefType.applyRef[NonEmptyString](rU) | |
clientSecret <- RefType.applyRef[NonEmptyString](cS) | |
code <- cc.fold("Code is required but given as Optional".asLeft[NonEmptyString])(RefType.applyRef[NonEmptyString](_)) | |
} yield ValidAuthorizeRequest(clientId, redirectUri, clientSecret, code) | |
// this gives me Either[String, ValidAuthorizeResult] | |
result match { | |
// THIS IS WRONG. Result[A] is not isomorphic to either | |
case e@Left(_) => Failed(e) | |
case r@Right(_) => Passed(r) | |
} | |
} | |
// I can always do this by hand but it would be nice to key into the validation syntax directly | |
// esp in the case of deeply nested objects each with their own instance of Validate | |
object ValidAuthorizeRequest { | |
def from(req: AuthorizeRequest): Either[String, ValidAuthorizeRequest] = for { | |
clientId <- refineV[NonEmpty](req.clientId) | |
redirectUri <- refineV[Uri](req.redirectUri) | |
clientSecret <- refineV[NonEmpty](req.clientSecret) | |
code <- req.code.fold("Code is required but given as Optional".asLeft[NonEmptyString])(refineV[NonEmpty](_)) | |
} yield ValidAuthorizeRequest(clientId, redirectUri, clientSecret, code) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment