Skip to main content

extras-render module

Import

import refined4s.modules.extras.derivation.types.all.given
import refined4s.modules.extras.derivation.*

Use Drived Instances for Pre-defined Types

To make Newtype, Refined and InlinedRefined have Render type-class instances derived from the actual values, you can simply use

import refined4s.modules.extras.derivation.types.all.given
NOTE

This works only when the actual type already has Render.

info

Using refined4s.modules.extras.derivation.types.all.given is required only when Render is required for the pre-defined types.
So if you want your Newtype or Refined or InlinedRefined to have Render instances,
you can use pre-defined traits for extras or the deriving method instead.

import refined4s.*
import refined4s.types.all.*

import extras.render.*
import extras.render.syntax.*

def renderA[A: Render](a: A): Unit = println(a.render)

With derivation.types.all,

import refined4s.modules.extras.derivation.types.all.given

final case class Person(name: NonEmptyString)
object Person {
given renderPerson: Render[Person] = person => render"Person(name=${person.name})"
}

renderA(NonEmptyString("Tony Stark"))
// Tony Stark

val thor = Person(NonEmptyString("Thor Odinson"))
// thor: Person = Person(name = "Thor Odinson")
renderA(thor)
// Person(name=Thor Odinson)

val captainAmerica = Person(NonEmptyString("Steve Rogers"))
// captainAmerica: Person = Person(name = "Steve Rogers")
renderA(captainAmerica)
// Person(name=Steve Rogers)

With Explicit Pre-defined extras-render Support

There are the following pre-defined traits to support extras' Render.

  • refined4s.modules.extras.derivation.ExtrasRender
NOTE

This works only when the actual type already has Render.

import refined4s.*
import refined4s.modules.extras.derivation.*

type Name = Name.Type
object Name extends Newtype[String] with ExtrasRender[String]

type NotEmptyStr = NotEmptyStr.Type
object NotEmptyStr extends Refined[String] with ExtrasRender[String] {
inline def invalidReason(a: String): String = "non-empty String"

inline def predicate(a: String): Boolean = a != ""
}

import extras.render.*
import extras.render.syntax.*

final case class Person(name: Name)

final case class Item(id: NotEmptyStr)

import extras.render.syntax.*

def renderA[A: Render](a: A): Unit = println(a.render)
renderA(Name("Tony Stark"))
// Tony Stark

renderA(NotEmptyStr("Thor Odinson"))
// Thor Odinson

renderA(Person(Name("Steve Rogers")).name)
// Steve Rogers

renderA(Item(NotEmptyStr("abc-999")).id)
// abc-999

With deriving Method

If you want to have explicit Render type-class instances in your Newtype or Refined or InlinedRefined, you can use the deriving method.

NOTE

This works only when the actual type already has Render.

import cats.*

import refined4s.*
import refined4s.modules.extras.derivation.*

import extras.render.*

type Name = Name.Type
object Name extends Newtype[String] {
given renderName: Render[Name] = deriving[Render]
}

type NotEmptyStr = NotEmptyStr.Type
object NotEmptyStr extends Refined[String] {
inline def invalidReason(a: String): String = "non-empty String"

inline def predicate(a: String): Boolean = a != ""

given renderNotEmptyStr: Render[NotEmptyStr] = deriving[Render]
}

import extras.render.syntax.*

final case class Person(name: Name)

final case class Item(id: NotEmptyStr)

import extras.render.syntax.*

def renderA[A: Render](a: A): Unit = println(a.render)
renderA(Name("Tony Stark"))
// Tony Stark

renderA(NotEmptyStr("Thor Odinson"))
// Thor Odinson

renderA(Person(Name("Steve Rogers")).name)
// Steve Rogers

renderA(Item(NotEmptyStr("abc-999")).id)
// abc-999