Package

com.gu

scanamo

Permalink

package scanamo

Visibility
  1. Public
  2. All

Type Members

  1. trait DerivedDynamoFormat extends AnyRef

    Permalink
  2. trait DynamoFormat[T] extends Serializable

    Permalink

    Type class for defining serialisation to and from DynamoDB's AttributeValue

    Type class for defining serialisation to and from DynamoDB's AttributeValue

    >>> val listOptionFormat = DynamoFormat[List[Option[Int]]]
    >>> listOptionFormat.read(listOptionFormat.write(List(Some(1), None, Some(3))))
    Right(List(Some(1), None, Some(3)))

    Also supports automatic derivation for case classes

    >>> case class Farm(animals: List[String])
    >>> case class Farmer(name: String, age: Long, farm: Farm)
    >>> val farmerF = DynamoFormat[Farmer]
    >>> farmerF.read(farmerF.write(Farmer("McDonald", 156L, Farm(List("sheep", "cow")))))
    Right(Farmer(McDonald,156,Farm(List(sheep, cow))))

    and for sealed trait + case object hierarchies

    >>> sealed trait Animal
    >>> case object Aardvark extends Animal
    >>> case object Zebra extends Animal
    >>> case class Pet(name: String, animal: Animal)
    >>> val petF = DynamoFormat[Pet]
    >>> petF.read(petF.write(Pet("Amy", Aardvark)))
    Right(Pet(Amy,Aardvark))
    
    >>> petF.read(petF.write(Pet("Zebediah", Zebra)))
    Right(Pet(Zebediah,Zebra))

    Problems reading a value are detailed

    >>> import cats.syntax.either._
    
    >>> case class Developer(name: String, age: String, problems: Int)
    >>> val invalid = DynamoFormat[Farmer].read(DynamoFormat[Developer].write(Developer("Alice", "none of your business", 99)))
    >>> invalid
    Left(InvalidPropertiesError(NonEmptyList(PropertyReadError(age,NoPropertyOfType(N,{S: none of your business,})), PropertyReadError(farm,MissingProperty))))
    
    >>> invalid.leftMap(cats.Show[error.DynamoReadError].show)
    Left('age': not of type: 'N' was '{S: none of your business,}', 'farm': missing)

    Optional properties are defaulted to None

    >>> case class LargelyOptional(a: Option[String], b: Option[String])
    >>> DynamoFormat[LargelyOptional].read(DynamoFormat[Map[String, String]].write(Map("b" -> "X")))
    Right(LargelyOptional(None,Some(X)))

    Custom formats can often be most easily defined using DynamoFormat.coercedXmap, DynamoFormat.xmap or DynamoFormat.iso

  3. trait EnumDynamoFormat extends DerivedDynamoFormat

    Permalink

    prop> sealed trait Animal
    prop> case object Aardvark extends Animal
    prop> case object Hippopotamus extends Animal
    prop> case object Zebra extends Animal
    
    prop> import org.scalacheck._
    prop> implicit val arbitraryAnimal: Arbitrary[Animal] = Arbitrary(Gen.oneOf(List(Aardvark, Hippopotamus, Zebra)))
    
    prop> (a: Animal) =>
        | DynamoFormat[Animal].read(DynamoFormat[Animal].write(a)) == Right(a)
    >>> DynamoFormat[Animal].write(Zebra).getS
    Zebra
  4. abstract class EnumerationDynamoFormat[T] extends DynamoFormat[T]

    Permalink

Value Members

  1. object DynamoFormat extends EnumDynamoFormat with Serializable

    Permalink
  2. package error

    Permalink

Ungrouped