Skip to content

Commit 5935805

Browse files
committed
Reuse Field
1 parent 64a9eea commit 5935805

File tree

4 files changed

+55
-52
lines changed

4 files changed

+55
-52
lines changed

modules/core/jvm/src/main/scala/internal/decoding.scala

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,30 @@ object decoding {
177177
var error: ReadError = null
178178

179179
while (i < record.fields.length && error == null) {
180-
val field = record.fields(i)
181-
map.get(field.name) match {
182-
case None =>
183-
error = ReadError(
184-
s"required field ${field.name} does not contain a value"
185-
)
186-
case Some(value) =>
187-
field.schema.read(value) match {
188-
case Left(err) => error = err
189-
case Right(v) => decodedValues(i) = v
180+
record.fields(i) match {
181+
case Field.Optional(name, schema, get) =>
182+
map.get(name) match {
183+
case None => decodedValues(i) = None
184+
case Some(value) =>
185+
schema.read(value) match {
186+
case Left(err) => error = err
187+
case Right(v) => decodedValues(i) = Some(v)
188+
}
190189
}
190+
191+
case Field.Required(name, schema, get) =>
192+
map.get(name) match {
193+
case None =>
194+
error = ReadError(
195+
s"required field $name does not contain a value"
196+
)
197+
case Some(value) =>
198+
schema.read(value) match {
199+
case Left(err) => error = err
200+
case Right(v) => decodedValues(i) = v
201+
}
202+
}
203+
191204
}
192205
i += 1
193206
}

modules/core/jvm/src/main/scala/internal/encoding.scala

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,24 @@ object encoding {
111111

112112
val map =
113113
new java.util.IdentityHashMap[String, AttributeValue](fieldCount)
114+
114115
while (i < record.fields.length && error == null) {
115-
val field = record.fields(i)
116-
val fieldValue = field.get(value)
117-
field.schema.write(fieldValue.asInstanceOf[field.A]) match {
118-
case Left(err) => error = err
119-
case Right(v) => map.put(fieldNames(i), v.value)
116+
record.fields(i) match {
117+
case Field.Required(name, schema, get) =>
118+
schema.write(get(value)) match {
119+
case Left(err) => error = err
120+
case Right(v) => map.put(name, v.value)
121+
}
122+
case Field.Optional(name, schema, get) =>
123+
val fieldValue = get(value)
124+
if (fieldValue != None) {
125+
schema.write(fieldValue.get) match {
126+
case Left(err) => error = err
127+
case Right(v) => map.put(name, v.value)
128+
}
129+
}
120130
}
131+
121132
i += 1
122133
}
123134

modules/core/shared/src/main/scala/Schema.scala

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -171,29 +171,8 @@ object Schema {
171171

172172
def nullable[A](implicit s: Schema[A]): Schema[Option[A]] = s.nullable
173173

174-
sealed trait RecordField[R] {
175-
type A
176-
def name: String
177-
def schema: Schema[A]
178-
def get: R => A
179-
}
180-
181-
object RecordField {
182-
def apply[R, A0](
183-
name0: String,
184-
schema0: Schema[A0],
185-
get0: R => A0
186-
): RecordField[R] =
187-
new RecordField[R] {
188-
type A = A0
189-
def name = name0
190-
def schema = schema0
191-
def get = get0
192-
}
193-
}
194-
195174
case class OptimizedRecord[R, A](
196-
fields: List[RecordField[R]],
175+
fields: List[Field[R, _]],
197176
build: List[Any] => A
198177
)
199178

@@ -217,9 +196,7 @@ object Schema {
217196

218197
def ap[X, Y](
219198
ff: OptimizedRecord[R, X => Y]
220-
)(
221-
fa: OptimizedRecord[R, X]
222-
): OptimizedRecord[R, Y] = {
199+
)(fa: OptimizedRecord[R, X]): OptimizedRecord[R, Y] =
223200
OptimizedRecord(
224201
ff.fields ++ fa.fields,
225202
values => {
@@ -230,19 +207,18 @@ object Schema {
230207
f(x)
231208
}
232209
)
233-
}
234210
}
235211

236212
fa.foldMap(new (Field[R, *] ~> λ[α => OptimizedRecord[R, α]]) {
237213
def apply[X](field: Field[R, X]): OptimizedRecord[R, X] = field match {
238-
case Field.Required(name, schema, get) =>
214+
case f @ Field.Required(name, schema, get) =>
239215
OptimizedRecord(
240-
List(RecordField(name, schema, get)),
216+
List(f),
241217
values => values.head.asInstanceOf[X]
242218
)
243-
case Field.Optional(name, schema, get) =>
219+
case f @ Field.Optional(name, schema, get) =>
244220
OptimizedRecord(
245-
List(RecordField(name, schema.nullable, get)),
221+
List(f),
246222
values => values.head.asInstanceOf[X]
247223
)
248224
}
@@ -316,15 +292,16 @@ object Schema {
316292
case object StrSet extends Schema[NonEmptySet[String]]
317293
case class Dictionary[A](value: Schema[A]) extends Schema[Map[String, A]]
318294
case class Sequence[A](value: Schema[A]) extends Schema[List[A]]
295+
319296
case class Record[R](
320-
fields: List[RecordField[R]],
297+
fields: List[Field[R, ?]],
321298
build: List[Any] => R,
322299
fieldNames: Array[String]
323300
) extends Schema[R]
324301

325302
object Record {
326303
def apply[R](
327-
fields: List[RecordField[R]],
304+
fields: List[Field[R, ?]],
328305
build: List[Any] => R
329306
): Record[R] = {
330307
val fieldNames = fields.map(_.name).toArray
@@ -336,7 +313,10 @@ object Schema {
336313
case class Isos[A](value: XMap[A]) extends Schema[A]
337314
case class Defer[A](value: () => Schema[A]) extends Schema[A]
338315

339-
sealed trait Field[R, E]
316+
sealed trait Field[R, E] {
317+
def name: String
318+
}
319+
340320
object Field {
341321
case class Required[R, E](
342322
name: String,

modules/core/shared/src/test/scala/SchemaSuite.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,14 @@ class SchemaSuite extends ScalaCheckSuite {
9191

9292
val output = schema
9393
.write(data)
94-
.toOption
9594

96-
assertEquals(output, expected.some, clue(data))
95+
assertEquals(output, expected.asRight, clue(data))
9796

9897
val roundTrip = output.flatMap { output =>
99-
schema.read(output).toOption
98+
schema.read(output)
10099
}
101100

102-
assertEquals(roundTrip, data.some)
101+
assertEquals(roundTrip, data.asRight)
103102
}
104103

105104
def checkNotFail[A](schema: Schema[A], data: A) = {

0 commit comments

Comments
 (0)