|
1 | 1 | package scynamo |
2 | 2 |
|
3 | 3 | import cats.data.EitherNec |
4 | | -import cats.syntax.either._ |
| 4 | +import cats.syntax.all._ |
5 | 5 | import org.scalatest.Inside |
6 | | -import scynamo.ScynamoEncoderTest.{Foo, Foo2, Snake} |
| 6 | +import scynamo.syntax.all._ |
| 7 | +import scynamo.ScynamoEncoderTest._ |
7 | 8 | import scynamo.StackFrame.{Attr, Case, Index, MapKey} |
8 | 9 | import scynamo.wrapper.{ScynamoBinarySet, ScynamoNumberSet, ScynamoStringSet} |
9 | 10 | import software.amazon.awssdk.core.SdkBytes |
10 | 11 | import software.amazon.awssdk.services.dynamodb.model.AttributeValue |
| 12 | +import scala.jdk.CollectionConverters._ |
11 | 13 |
|
12 | 14 | class ScynamoEncoderTest extends UnitTest { |
13 | 15 | "ScynamoEncoder" should { |
@@ -138,14 +140,49 @@ class ScynamoEncoderTest extends UnitTest { |
138 | 140 | .encodeMap(Snake(1, Some(Snake(2, None)))) |
139 | 141 | .map(attrs => Option(attrs.get("tail").m.get("tail"))) should ===(Right(None)) |
140 | 142 | } |
| 143 | + |
| 144 | + "allow modifying encoded maps" in { |
| 145 | + val prices = Typed("price", Map("milk" -> 1.29, "hummus" -> 0.99)) |
| 146 | + prices.encodedMap.map(_.asScala) shouldBe Right( |
| 147 | + Map( |
| 148 | + "type" -> AttributeValue.builder.s("price").build(), |
| 149 | + "milk" -> AttributeValue.builder.n("1.29").build(), |
| 150 | + "hummus" -> AttributeValue.builder.n("0.99").build() |
| 151 | + ) |
| 152 | + ) |
| 153 | + } |
| 154 | + |
| 155 | + "allow modifying encoded objects" in { |
| 156 | + val prices = Typed("snake", Snake(42, None)) |
| 157 | + prices.encodedMap.map(_.asScala) shouldBe Right( |
| 158 | + Map( |
| 159 | + "type" -> AttributeValue.builder.s("snake").build(), |
| 160 | + "head" -> AttributeValue.builder.n("42").build() |
| 161 | + ) |
| 162 | + ) |
| 163 | + } |
141 | 164 | } |
142 | 165 | } |
143 | 166 |
|
144 | 167 | object ScynamoEncoderTest { |
| 168 | + case class Typed[A](tpe: String, value: A) |
| 169 | + object Typed { |
| 170 | + implicit def encoder[A: ObjectScynamoEncoder]: ObjectScynamoEncoder[Typed[A]] = |
| 171 | + ObjectScynamoEncoder.instance { case Typed(tpe, value) => |
| 172 | + for { |
| 173 | + encodedType <- tpe.encoded |
| 174 | + encodedValue <- value.encodedMap |
| 175 | + } yield { |
| 176 | + encodedValue.put("type", encodedType) |
| 177 | + encodedValue |
| 178 | + } |
| 179 | + } |
| 180 | + } |
| 181 | + |
145 | 182 | case class Snake[A](head: A, tail: Option[Snake[A]]) |
146 | 183 | object Snake { |
147 | | - implicit def codec[A: ScynamoCodec]: ObjectScynamoCodec[Snake[A]] = |
148 | | - scynamo.generic.semiauto.deriveScynamoCodec[Snake[A]] |
| 184 | + implicit def codec[A: ScynamoEncoder]: ObjectScynamoEncoder[Snake[A]] = |
| 185 | + scynamo.generic.semiauto.deriveScynamoEncoder[Snake[A]] |
149 | 186 | } |
150 | 187 |
|
151 | 188 | case class Foo(i: Int) |
|
0 commit comments