Skip to content

Commit 4c858c0

Browse files
author
Georgi Krastev
authored
Allow modifying encoded maps and objects (#254)
1 parent 2a8049a commit 4c858c0

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

src/main/scala/scynamo/ScynamoEncoder.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import shapeless.tag.@@
1313
import software.amazon.awssdk.services.dynamodb.model.AttributeValue
1414

1515
import java.time.{Instant, YearMonth}
16-
import java.util.{Collections, UUID}
16+
import java.util.UUID
1717
import scala.collection.compat._
1818
import scala.collection.immutable.Seq
1919
import scala.concurrent.duration.{Duration, FiniteDuration}
@@ -201,7 +201,7 @@ object ObjectScynamoEncoder extends SemiautoDerivationEncoder {
201201
}
202202
}
203203

204-
NonEmptyChain.fromChain(allErrors).toLeft(Collections.unmodifiableMap(attrValues))
204+
NonEmptyChain.fromChain(allErrors).toLeft(attrValues)
205205
}
206206
}
207207

src/main/scala/scynamo/generic/GenericScynamoEncoder.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package scynamo.generic
33
import scynamo.ObjectScynamoEncoder
44
import shapeless.{LabelledGeneric, Lazy}
55

6-
import java.util.Collections
7-
86
trait GenericScynamoEncoder[A] extends ObjectScynamoEncoder[A]
97

108
object GenericScynamoEncoder extends GenericScynamoEncoderInstances
@@ -14,5 +12,5 @@ trait GenericScynamoEncoderInstances {
1412
gen: LabelledGeneric.Aux[F, G],
1513
sg: Lazy[ShapelessScynamoEncoder[F, G]]
1614
): GenericScynamoEncoder[F] =
17-
value => sg.value.encodeMap(gen.to(value)).map(Collections.unmodifiableMap(_))
15+
value => sg.value.encodeMap(gen.to(value))
1816
}

src/test/scala/scynamo/ScynamoEncoderTest.scala

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package scynamo
22

33
import cats.data.EitherNec
4-
import cats.syntax.either._
4+
import cats.syntax.all._
55
import org.scalatest.Inside
6-
import scynamo.ScynamoEncoderTest.{Foo, Foo2, Snake}
6+
import scynamo.syntax.all._
7+
import scynamo.ScynamoEncoderTest._
78
import scynamo.StackFrame.{Attr, Case, Index, MapKey}
89
import scynamo.wrapper.{ScynamoBinarySet, ScynamoNumberSet, ScynamoStringSet}
910
import software.amazon.awssdk.core.SdkBytes
1011
import software.amazon.awssdk.services.dynamodb.model.AttributeValue
12+
import scala.jdk.CollectionConverters._
1113

1214
class ScynamoEncoderTest extends UnitTest {
1315
"ScynamoEncoder" should {
@@ -138,14 +140,49 @@ class ScynamoEncoderTest extends UnitTest {
138140
.encodeMap(Snake(1, Some(Snake(2, None))))
139141
.map(attrs => Option(attrs.get("tail").m.get("tail"))) should ===(Right(None))
140142
}
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+
}
141164
}
142165
}
143166

144167
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+
145182
case class Snake[A](head: A, tail: Option[Snake[A]])
146183
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]]
149186
}
150187

151188
case class Foo(i: Int)

0 commit comments

Comments
 (0)