Skip to content

Commit 0de1cfd

Browse files
authored
Merge pull request #23 from plokhotnyuk/add-schema-default-value
Add `Schema.defaultValue` implementation
2 parents b6f72ce + b95fb64 commit 0de1cfd

File tree

3 files changed

+115
-5
lines changed

3 files changed

+115
-5
lines changed

schema/shared/src/main/scala/zio/blocks/schema/Reflect.scala

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ sealed trait Reflect[F[_, _], A] extends Reflectable[A] { self =>
1717

1818
def doc(value: String): Reflect[F, A]
1919

20+
def defaultValue(value: => A): Reflect[F, A]
21+
2022
def examples(value: A, values: A*): Reflect[F, A]
2123

2224
def binding(implicit F: HasBinding[F]): Binding[NodeBinding, A]
@@ -46,6 +48,14 @@ object Reflect {
4648

4749
def doc(value: String): Record[F, A] = copy(doc = Doc.Text(value))
4850

51+
def defaultValue(value: => A): Record[F, A] =
52+
copy(recordBinding =
53+
recordBinding
54+
.asInstanceOf[Binding[BindingType.Record, A]]
55+
.defaultValue(value)
56+
.asInstanceOf[F[BindingType.Record, A]]
57+
)
58+
4959
def examples(value: A, values: A*): Record[F, A] =
5060
copy(recordBinding =
5161
recordBinding
@@ -146,6 +156,14 @@ object Reflect {
146156

147157
def doc(value: String): Variant[F, A] = copy(doc = Doc.Text(value))
148158

159+
def defaultValue(value: => A): Variant[F, A] =
160+
copy(variantBinding =
161+
variantBinding
162+
.asInstanceOf[Binding[BindingType.Variant, A]]
163+
.defaultValue(value)
164+
.asInstanceOf[F[BindingType.Variant, A]]
165+
)
166+
149167
def examples(value: A, values: A*): Variant[F, A] =
150168
copy(variantBinding =
151169
variantBinding
@@ -187,6 +205,14 @@ object Reflect {
187205

188206
def doc(value: String): Sequence[F, A, C] = copy(doc = Doc.Text(value))
189207

208+
def defaultValue(value: => C[A]): Sequence[F, A, C] =
209+
copy(seqBinding =
210+
seqBinding
211+
.asInstanceOf[Binding[BindingType.Seq[C], C[A]]]
212+
.defaultValue(value)
213+
.asInstanceOf[F[BindingType.Seq[C], C[A]]]
214+
)
215+
190216
def examples(value: C[A], values: C[A]*): Sequence[F, A, C] =
191217
copy(seqBinding =
192218
seqBinding
@@ -225,6 +251,14 @@ object Reflect {
225251

226252
def doc(value: String): Map[F, Key, Value, M] = copy(doc = Doc.Text(value))
227253

254+
def defaultValue(value: => M[Key, Value]): Map[F, Key, Value, M] =
255+
copy(mapBinding =
256+
mapBinding
257+
.asInstanceOf[Binding[BindingType.Map[M], M[Key, Value]]]
258+
.defaultValue(value)
259+
.asInstanceOf[F[BindingType.Map[M], M[Key, Value]]]
260+
)
261+
228262
def examples(value: M[Key, Value], values: M[Key, Value]*): Map[F, Key, Value, M] =
229263
copy(mapBinding =
230264
mapBinding
@@ -262,6 +296,14 @@ object Reflect {
262296

263297
def doc(value: String): Dynamic[F] = copy(doc = Doc.Text(value))
264298

299+
def defaultValue(value: => DynamicValue): Dynamic[F] =
300+
copy(dynamicBinding =
301+
dynamicBinding
302+
.asInstanceOf[Binding[BindingType.Dynamic, DynamicValue]]
303+
.defaultValue(value)
304+
.asInstanceOf[F[BindingType.Dynamic, DynamicValue]]
305+
)
306+
265307
def examples(value: DynamicValue, values: DynamicValue*): Dynamic[F] =
266308
copy(dynamicBinding =
267309
dynamicBinding
@@ -289,6 +331,14 @@ object Reflect {
289331

290332
def doc(value: String): Primitive[F, A] = copy(doc = Doc.Text(value))
291333

334+
def defaultValue(value: => A): Primitive[F, A] =
335+
copy(primitiveBinding =
336+
primitiveBinding
337+
.asInstanceOf[Binding[BindingType.Primitive, A]]
338+
.defaultValue(value)
339+
.asInstanceOf[F[BindingType.Primitive, A]]
340+
)
341+
292342
def examples(value: A, values: A*): Primitive[F, A] =
293343
copy(primitiveBinding =
294344
primitiveBinding
@@ -316,6 +366,8 @@ object Reflect {
316366

317367
def doc(value: String): Deferred[F, A] = copy(_value = () => _value().doc(value))
318368

369+
def defaultValue(value: => A): Deferred[F, A] = copy(_value = () => _value().defaultValue(value))
370+
319371
def examples(value: A, values: A*): Deferred[F, A] = copy(_value = () => _value().examples(value, values: _*))
320372

321373
def binding(implicit F: HasBinding[F]): Binding[NodeBinding, A] = value.binding

schema/shared/src/main/scala/zio/blocks/schema/Schema.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ final case class Schema[A](reflect: Reflect.Bound[A]) {
1919

2020
def defaultValue[B](optic: Optic.Bound[A, B], value: => B): Schema[A] = ??? // TODO
2121

22-
def defaultValue(value: => A): Schema[A] = ??? // TODO
22+
def defaultValue(value: => A): Schema[A] = Schema(reflect.defaultValue(value))
2323

2424
def derive[F <: codec.Format](format: F): format.TypeClass[A] = ??? // TODO
2525

@@ -41,7 +41,7 @@ final case class Schema[A](reflect: Reflect.Bound[A]) {
4141

4242
def examples: List[A] = reflect.binding.examples
4343

44-
def examples(value: A, values: A*): Schema[A] = Schema(reflect.examples(value, values: _*)) // TODO
44+
def examples(value: A, values: A*): Schema[A] = Schema(reflect.examples(value, values: _*))
4545

4646
def examples[B](optic: Optic.Bound[A, B]): List[B] = optic.focus.binding.examples
4747

schema/shared/src/test/scala/zio/blocks/schema/SchemaSpec.scala

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ object SchemaSpec extends ZIOSpecDefault {
3131
assert(Schema(long4))(not(equalTo(Schema[Long]))) &&
3232
assert(Schema(long5))(not(equalTo(Schema[Long])))
3333
},
34+
test("updates primitive default value") {
35+
assert(Schema[Int].reflect.binding.defaultValue)(isNone) &&
36+
assert(Schema[Int].defaultValue(1).reflect.binding.defaultValue.get.apply())(equalTo(1))
37+
},
3438
test("has access to primitive documentation") {
3539
val long1 = Primitive(
3640
primitiveType = PrimitiveType.Long(Validation.None),
@@ -41,6 +45,9 @@ object SchemaSpec extends ZIOSpecDefault {
4145
)
4246
assert(Schema(long1).doc)(equalTo(Doc("Long (positive)")))
4347
},
48+
test("updates primitive documentation") {
49+
assert(Schema[Int].doc("Int (updated)").doc)(equalTo(Doc("Int (updated)")))
50+
},
4451
test("has access to primitive examples") {
4552
val long1 = Primitive(
4653
primitiveType = PrimitiveType.Long(Validation.Numeric.Positive),
@@ -50,6 +57,9 @@ object SchemaSpec extends ZIOSpecDefault {
5057
modifiers = Nil
5158
)
5259
assert(Schema(long1).examples)(equalTo(List(1L, 2L, 3L)))
60+
},
61+
test("updates primitive examples") {
62+
assert(Schema[Int].examples(1, 2, 3).examples)(equalTo(List(1, 2, 3)))
5363
}
5464
),
5565
suite("Reflect.Record")(
@@ -110,6 +120,10 @@ object SchemaSpec extends ZIOSpecDefault {
110120
assert(record3.registers(0).usedRegisters)(equalTo(RegisterOffset(objects = 1))) &&
111121
assert(record3.usedRegisters)(equalTo(record3.registers.foldLeft(0)(_ + _.usedRegisters)))
112122
},
123+
test("updates record default value") {
124+
assert(Record.schema.reflect.binding.defaultValue)(isNone) &&
125+
assert(Record.schema.defaultValue(Record(1, 2)).reflect.binding.defaultValue.get.apply())(equalTo(Record(1, 2)))
126+
},
113127
test("has access to record documentation") {
114128
assert(Record.schema.doc)(equalTo(Doc("Record with 2 fields")))
115129
},
@@ -158,6 +172,10 @@ object SchemaSpec extends ZIOSpecDefault {
158172
assert(Schema(variant4))(not(equalTo(Variant.schema))) &&
159173
assert(Schema(variant5))(not(equalTo(Variant.schema)))
160174
},
175+
test("updates variant default value") {
176+
assert(Variant.schema.reflect.binding.defaultValue)(isNone) &&
177+
assert(Variant.schema.defaultValue(Case1(1.0)).reflect.binding.defaultValue.get.apply())(equalTo(Case1(1.0)))
178+
},
161179
test("has access to variant documentation") {
162180
assert(Variant.schema.doc)(equalTo(Doc("Variant with 2 cases")))
163181
},
@@ -205,6 +223,10 @@ object SchemaSpec extends ZIOSpecDefault {
205223
assert(Schema(sequence4))(not(equalTo(Schema[List[Double]]))) &&
206224
assert(Schema(sequence5))(not(equalTo(Schema[List[Double]])))
207225
},
226+
test("updates sequence default value") {
227+
assert(Schema[List[Int]].reflect.binding.defaultValue)(isNone) &&
228+
assert(Schema[List[Int]].defaultValue(Nil).reflect.binding.defaultValue.get.apply())(equalTo(Nil))
229+
},
208230
test("has access to sequence documentation") {
209231
val sequence1 = Reflect.Sequence[Binding, Double, List](
210232
element = Reflect.double,
@@ -305,6 +327,12 @@ object SchemaSpec extends ZIOSpecDefault {
305327
assert(Schema(map5))(not(equalTo(Schema[Map[Short, Float]]))) &&
306328
assert(Schema(map6))(not(equalTo(Schema[Map[Short, Float]])))
307329
},
330+
test("updates map default value") {
331+
assert(Schema[Map[Int, Long]].reflect.binding.defaultValue)(isNone) &&
332+
assert(Schema[Map[Int, Long]].defaultValue(Map.empty).reflect.binding.defaultValue.get.apply())(
333+
equalTo(Map.empty[Int, Long])
334+
)
335+
},
308336
test("has access to map documentation") {
309337
val map1 = Reflect.Map[Binding, Int, Long, Map](
310338
key = Reflect.int,
@@ -429,6 +457,23 @@ object SchemaSpec extends ZIOSpecDefault {
429457
assert(Schema(dynamic3))(not(equalTo(Schema(dynamic1)))) &&
430458
assert(Schema(dynamic4))(not(equalTo(Schema(dynamic1))))
431459
},
460+
test("updates dynamic default value") {
461+
val dynamic1 = Reflect.Dynamic[Binding](
462+
dynamicBinding = Binding.Dynamic(),
463+
doc = Doc.Empty,
464+
modifiers = Nil
465+
)
466+
assert(Schema(dynamic1).reflect.binding.defaultValue)(isNone) &&
467+
assert(
468+
Schema(dynamic1)
469+
.defaultValue(DynamicValue.Primitive(PrimitiveValue.Int(0)))
470+
.reflect
471+
.binding
472+
.defaultValue
473+
.get
474+
.apply()
475+
)(equalTo(DynamicValue.Primitive(PrimitiveValue.Int(0))))
476+
},
432477
test("has access to dynamic documentation") {
433478
val dynamic1 = Reflect.Dynamic[Binding](
434479
dynamicBinding = Binding.Dynamic(),
@@ -447,11 +492,11 @@ object SchemaSpec extends ZIOSpecDefault {
447492
},
448493
test("has access to dynamic examples") {
449494
val dynamic1 = Reflect.Dynamic[Binding](
450-
dynamicBinding = Binding.Dynamic(),
451-
doc = Doc("Dynamic"),
495+
dynamicBinding = Binding.Dynamic(examples = DynamicValue.Primitive(PrimitiveValue.Int(0)) :: Nil),
496+
doc = Doc.Empty,
452497
modifiers = Nil
453498
)
454-
assert(Schema(dynamic1).examples)(equalTo(Nil))
499+
assert(Schema(dynamic1).examples)(equalTo(DynamicValue.Primitive(PrimitiveValue.Int(0)) :: Nil))
455500
},
456501
test("updates dynamic examples") {
457502
val dynamic1 = Reflect.Dynamic[Binding](
@@ -481,6 +526,19 @@ object SchemaSpec extends ZIOSpecDefault {
481526
assert(Schema(deferred4))(not(equalTo(Schema(deferred1)))) &&
482527
assert(Schema(deferred5))(not(equalTo(Schema(deferred1))))
483528
},
529+
test("updates deferred default value") {
530+
val deferred1 = Reflect.Deferred[Binding, Int] { () =>
531+
Primitive(
532+
PrimitiveType.Int(Validation.Numeric.Positive),
533+
Binding.Primitive.int,
534+
TypeName.int,
535+
Doc.Empty,
536+
Nil
537+
)
538+
}
539+
assert(Schema(deferred1).reflect.binding.defaultValue)(isNone) &&
540+
assert(Schema(deferred1).defaultValue(1).reflect.binding.defaultValue.get.apply())(equalTo(1))
541+
},
484542
test("has access to deferred documentation") {
485543
val deferred1 = Reflect.Deferred[Binding, Int] { () =>
486544
Primitive(

0 commit comments

Comments
 (0)