Skip to content

Commit e78825e

Browse files
committed
Added support for class naming in DefType and introduced new RW methods with customizable class names
1 parent 850ae1d commit e78825e

3 files changed

Lines changed: 78 additions & 8 deletions

File tree

core/shared/src/main/scala/fabric/define/DefType.scala

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ sealed trait DefType {
3434

3535
def describe(desc: String): DefType = DefType.Described(this, Some(desc))
3636

37+
def withClassName(cn: String): DefType = DefType.Classed(this, cn)
38+
3739
def isOpt: Boolean = false
3840

3941
def isNull: Boolean = false
@@ -82,6 +84,9 @@ object DefType {
8284

8385
private def dt2V(dt: DefType): Json = dt match {
8486
case Described(inner, desc) => withDesc(dt2V(inner).asObj, desc)
87+
case Classed(inner, cn) =>
88+
val base = dt2V(inner).asObj
89+
base.merge(fabric.Obj("className" -> str(cn))).asObj
8590
case Obj(map, cn, desc) => withDesc(
8691
obj(
8792
"type" -> str("object"),
@@ -111,6 +116,11 @@ object DefType {
111116

112117
private def readDesc(o: fabric.Obj): Option[String] = o.get("description").map(_.asString)
113118

119+
private def withClass(dt: DefType, o: fabric.Obj): DefType = o.get("className").map(_.asString) match {
120+
case Some(cn) => Classed(dt, cn)
121+
case None => dt
122+
}
123+
114124
private def v2dt(v: Json): DefType = {
115125
val o = v.asObj
116126
val desc = readDesc(o)
@@ -130,20 +140,20 @@ object DefType {
130140
)
131141
case "array" => Arr(t = v2dt(o.value("value")), description = desc)
132142
case "optional" => Opt(v2dt(o.value("value")), description = desc)
133-
case "string" => desc.fold[DefType](Str)(Str.describe)
143+
case "string" => withClass(desc.fold[DefType](Str)(Str.describe), o)
134144
case "numeric" => o.value("precision").asString match {
135-
case "integer" => desc.fold[DefType](Int)(Int.describe)
136-
case "decimal" => desc.fold[DefType](Dec)(Dec.describe)
145+
case "integer" => withClass(desc.fold[DefType](Int)(Int.describe), o)
146+
case "decimal" => withClass(desc.fold[DefType](Dec)(Dec.describe), o)
137147
}
138-
case "boolean" => desc.fold[DefType](Bool)(Bool.describe)
148+
case "boolean" => withClass(desc.fold[DefType](Bool)(Bool.describe), o)
139149
case "enum" => Enum(o.value("values").asVector.toList, o.get("className").map(_.asString), description = desc)
140150
case "poly" => Poly(
141151
o.value("values").asMap.map { case (key, json) => key -> v2dt(json) },
142152
o.get("className").map(_.asString),
143153
description = desc
144154
)
145-
case "json" => desc.fold[DefType](Json)(Json.describe)
146-
case "null" => desc.fold[DefType](Null)(Null.describe)
155+
case "json" => withClass(desc.fold[DefType](Json)(Json.describe), o)
156+
case "null" => withClass(desc.fold[DefType](Null)(Null.describe), o)
147157
}
148158
}
149159

@@ -174,6 +184,7 @@ object DefType {
174184
}
175185
case class Arr(t: DefType, override val description: Option[String] = None) extends DefType {
176186
override def className: Option[String] = None
187+
def apply(className: String): DefType = Classed(this, className)
177188
override def describe(desc: String): Arr = copy(description = Some(desc))
178189

179190
override def merge(that: DefType): DefType = that match {
@@ -210,11 +221,13 @@ object DefType {
210221
}
211222
case object Str extends DefType {
212223
override def className: Option[String] = None
224+
def apply(className: String): DefType = Classed(Str, className)
213225

214226
override protected def template(path: JsonPath, config: TemplateConfig): Json = str(config.string(path))
215227
}
216228
case object Int extends DefType {
217229
override def className: Option[String] = None
230+
def apply(className: String): DefType = Classed(Int, className)
218231

219232
override def merge(that: DefType): DefType = that match {
220233
case DefType.Dec => that
@@ -225,6 +238,7 @@ object DefType {
225238
}
226239
case object Dec extends DefType {
227240
override def className: Option[String] = None
241+
def apply(className: String): DefType = Classed(Dec, className)
228242

229243
override def merge(that: DefType): DefType = that match {
230244
case DefType.Int => this
@@ -235,11 +249,13 @@ object DefType {
235249
}
236250
case object Bool extends DefType {
237251
override def className: Option[String] = None
252+
def apply(className: String): DefType = Classed(Bool, className)
238253

239254
override protected def template(path: JsonPath, config: TemplateConfig): Json = bool(config.bool(path))
240255
}
241256
case object Json extends DefType {
242257
override def className: Option[String] = None
258+
def apply(className: String): DefType = Classed(Json, className)
243259

244260
override protected def template(path: JsonPath, config: TemplateConfig): Json = config.json(path)
245261
}
@@ -265,6 +281,17 @@ object DefType {
265281
override def merge(that: DefType): DefType = dt.merge(that)
266282
override protected def template(path: JsonPath, config: TemplateConfig): Json = dt.template(path, config)
267283
}
284+
case class Classed(dt: DefType, cn: String) extends DefType {
285+
override def className: Option[String] = Some(cn)
286+
override def description: Option[String] = dt.description
287+
override def isOpt: Boolean = dt.isOpt
288+
override def isNull: Boolean = dt.isNull
289+
override def opt: DefType = Classed(dt.opt, cn)
290+
override def withClassName(cn: String): DefType = copy(cn = cn)
291+
override def describe(desc: String): DefType = Classed(dt.describe(desc), cn)
292+
override def merge(that: DefType): DefType = dt.merge(that)
293+
override protected def template(path: JsonPath, config: TemplateConfig): Json = dt.template(path, config)
294+
}
268295
case object Null extends DefType {
269296
override def className: Option[String] = None
270297

core/shared/src/main/scala/fabric/define/FabricGenerator.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ object FabricGenerator {
5353
}
5454
def typeFor(name: String, dt: DefType): String = dt match {
5555
case DefType.Described(inner, _) => typeFor(name, inner)
56+
case DefType.Classed(inner, cn) =>
57+
val simpleName = if (cn.contains('.')) cn.substring(cn.lastIndexOf('.') + 1) else cn
58+
simpleName
5659
case DefType.Obj(map, _, _) =>
5760
val className = resolver(name)
5861
additional = generate(className, map) :: additional

core/shared/src/main/scala/fabric/rw/RW.scala

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,52 @@ object RW extends CompileRW {
6464
override val definition: DefType = DefType.Enum(list.map(t => Str(asString(t))), Some(className))
6565
}
6666

67-
def string[T](asString: T => String, fromString: String => T): RW[T] = new RW[T] {
67+
def string[T](asString: T => String, fromString: String => T, className: Option[String] = None): RW[T] = new RW[T] {
6868
override def write(value: Json): T = fromString(value.asString)
6969

7070
override def read(t: T): Json = str(asString(t))
7171

72-
override def definition: DefType = DefType.Str
72+
override def definition: DefType = className.fold[DefType](DefType.Str)(DefType.Str(_))
73+
}
74+
75+
def int[T](asInt: T => Int, fromInt: Int => T, className: Option[String] = None): RW[T] = new RW[T] {
76+
override def write(value: Json): T = fromInt(value.asInt)
77+
78+
override def read(t: T): Json = asInt(t).json
79+
80+
override def definition: DefType = className.fold[DefType](DefType.Int)(DefType.Int(_))
81+
}
82+
83+
def long[T](asLong: T => Long, fromLong: Long => T, className: Option[String] = None): RW[T] = new RW[T] {
84+
override def write(value: Json): T = fromLong(value.asLong)
85+
86+
override def read(t: T): Json = asLong(t).json
87+
88+
override def definition: DefType = className.fold[DefType](DefType.Int)(DefType.Int(_))
89+
}
90+
91+
def double[T](asDouble: T => Double, fromDouble: Double => T, className: Option[String] = None): RW[T] = new RW[T] {
92+
override def write(value: Json): T = fromDouble(value.asDouble)
93+
94+
override def read(t: T): Json = num(asDouble(t))
95+
96+
override def definition: DefType = className.fold[DefType](DefType.Dec)(DefType.Dec(_))
97+
}
98+
99+
def dec[T](asDec: T => BigDecimal, fromDec: BigDecimal => T, className: Option[String] = None): RW[T] = new RW[T] {
100+
override def write(value: Json): T = fromDec(value.asBigDecimal)
101+
102+
override def read(t: T): Json = num(asDec(t))
103+
104+
override def definition: DefType = className.fold[DefType](DefType.Dec)(DefType.Dec(_))
105+
}
106+
107+
def bool[T](asBool: T => Boolean, fromBool: Boolean => T, className: Option[String] = None): RW[T] = new RW[T] {
108+
override def write(value: Json): T = fromBool(value.asBool.value)
109+
110+
override def read(t: T): Json = fabric.Bool(asBool(t))
111+
112+
override def definition: DefType = className.fold[DefType](DefType.Bool)(DefType.Bool(_))
73113
}
74114

75115
def wrapped[T](key: String, asJson: T => Json, fromJson: Json => T, definition: DefType = DefType.Json): RW[T] =

0 commit comments

Comments
 (0)