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
This works only when the actual type already has Render.
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
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.
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