Skip to content

Commit 0690bdf

Browse files
committedOct 20, 2022
Fix document encoders of maps with newtype keys
1 parent 73e7aa0 commit 0690bdf

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed
 

‎modules/core/src/smithy4s/internals/DocumentKeyEncoder.scala

+19-1
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,15 @@ import smithy4s.schema.EnumValue
2525
import smithy4s.schema.Primitive
2626
import smithy4s.schema.Primitive._
2727
import smithy4s.schema.SchemaVisitor
28+
import smithy4s.schema.Schema
2829

29-
trait DocumentKeyEncoder[A] {
30+
trait DocumentKeyEncoder[A] { self =>
3031
def apply(a: A): String
32+
33+
def contramap[B](f: B => A): DocumentKeyEncoder[B] =
34+
new DocumentKeyEncoder[B] {
35+
def apply(b: B): String = self(f(b))
36+
}
3137
}
3238

3339
object DocumentKeyEncoder {
@@ -89,5 +95,17 @@ object DocumentKeyEncoder {
8995
values: List[EnumValue[E]],
9096
total: E => EnumValue[E]
9197
): OptDocumentKeyEncoder[E] = Some { a => total(a).stringValue }
98+
99+
override def biject[A, B](
100+
schema: Schema[A],
101+
bijection: Bijection[A, B]
102+
): OptDocumentKeyEncoder[B] =
103+
apply(schema).map(_.contramap(bijection.from))
104+
105+
override def refine[A, B](
106+
schema: Schema[A],
107+
refinement: Refinement[A, B]
108+
): OptDocumentKeyEncoder[B] =
109+
apply(schema).map(_.contramap(refinement.from))
92110
}
93111
}

‎modules/core/test/src/smithy4s/DocumentSpec.scala

+60
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,64 @@ class DocumentSpec() extends FunSuite {
224224
expect(roundTripped == Right(defTest))
225225
}
226226

227+
test("defaults should not be applied when field is provided") {
228+
val defTest = DefTest(12, "test2")
229+
230+
val document = Document.encode(defTest)
231+
import Document._
232+
val expectedDocument =
233+
obj(
234+
"int" -> fromInt(12),
235+
"str" -> fromString("test2")
236+
)
237+
238+
val roundTripped = Document.decode[DefTest](document)
239+
240+
expect(document == expectedDocument)
241+
expect(roundTripped == Right(defTest))
242+
}
243+
244+
test("encoding maps keyed with newtypes should not change the encoding") {
245+
case class Key(string: String)
246+
val keySchema = bijection(string, Key(_), (_: Key).string)
247+
implicit val mapSchema: Schema[Map[Key, Int]] = map(keySchema, int)
248+
249+
val mapTest = Map(Key("hello") -> 1, Key("world") -> 2)
250+
251+
val document = Document.encode(mapTest)
252+
import Document._
253+
val expectedDocument =
254+
obj(
255+
"hello" -> fromInt(1),
256+
"world" -> fromInt(2)
257+
)
258+
259+
val roundTripped = Document.decode[Map[Key, Int]](document)
260+
261+
expect.same(document, expectedDocument)
262+
expect.same(roundTripped, Right(mapTest))
263+
}
264+
265+
test(
266+
"encoding maps keyed with validated types should not change the encoding"
Has conversations. Original line has conversations.
267+
) {
268+
val keySchema = int.validated(smithy.api.Range(None, Some(BigDecimal(3))))
269+
implicit val mapSchema: Schema[Map[Int, Int]] = map(keySchema, int)
270+
271+
val mapTest = Map(1 -> 1, 2 -> 2)
272+
273+
val document = Document.encode(mapTest)
274+
import Document._
275+
val expectedDocument =
276+
obj(
277+
"1" -> fromInt(1),
278+
"2" -> fromInt(2)
279+
)
280+
281+
val roundTripped = Document.decode[Map[Int, Int]](document)
282+
283+
expect.same(document, expectedDocument)
284+
expect.same(roundTripped, Right(mapTest))
285+
}
286+
227287
}

0 commit comments

Comments
 (0)
Please sign in to comment.