Skip to content

Commit 83cf1bd

Browse files
committed
feat: XML codec implemented
1 parent 9353245 commit 83cf1bd

File tree

3 files changed

+46
-22
lines changed

3 files changed

+46
-22
lines changed

build.sbt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,13 +307,14 @@ lazy val zioSchemaXml = project
307307
.settings(
308308
libraryDependencies ++= Seq(
309309
"org.scala-lang.modules" %% "scala-xml" % scalaXmlVersion,
310-
"org.scalaxb" %% "scalaxb" % "1.11.1",
310+
"org.scalaxb" %% "scalaxb" % "1.12.4",
311311
"org.scala-lang.modules" %% "scala-parser-combinators" % "2.4.0",
312312
"javax.xml.bind" % "jaxb-api" % "2.3.1"
313313
),
314314
Compile / scalaxb / scalaxbXsdSource := new File(baseDirectory.value, "src/test/resources"),
315-
Compile / scalaxb / scalaxbDispatchVersion := "1.1.3",
316-
Compile / scalaxb / scalaxbPackageName := "generated"
315+
Compile / scalaxb / scalaxbPackageName := "generated",
316+
Compile / scalacOptions := (Compile / scalacOptions).value.filterNot(_ == "-Xfatal-warnings"),
317+
mimaPreviousArtifacts := Set()
317318
)
318319
.settings(testDeps)
319320

zio-schema-xml/src/main/scala/zio/schema/codec/XmlCodec.scala

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,24 +110,42 @@ object XmlCodec {
110110

111111
case Schema.Optional(innerSchema, _) =>
112112
value.asInstanceOf[Option[Any]] match {
113-
case Some(v) => encodeNode(v, innerSchema, name, config)
113+
case Some(v) => encodeNode(v, innerSchema.asInstanceOf[Schema[Any]], name, config)
114114
case None => if (config.omitEmptyElements) Seq.empty else Seq(Elem(null, name, Null, TopScope, true))
115115
}
116116

117117
case Schema.Sequence(elementSchema, _, g, _, _) =>
118-
encodeSequence(g(value), elementSchema, name, config)
118+
encodeSequence(g(value), elementSchema.asInstanceOf[Schema[Any]], name, config)
119119

120120
case Schema.Map(keySchema, valueSchema, _) =>
121-
encodeMap(value.asInstanceOf[Map[Any, Any]], keySchema, valueSchema, name, config)
121+
encodeMap(
122+
value.asInstanceOf[Map[Any, Any]],
123+
keySchema.asInstanceOf[Schema[Any]],
124+
valueSchema.asInstanceOf[Schema[Any]],
125+
name,
126+
config
127+
)
122128

123129
case Schema.Set(elementSchema, _) =>
124-
encodeSet(value.asInstanceOf[Set[Any]], elementSchema, name, config)
130+
encodeSet(value.asInstanceOf[Set[Any]], elementSchema.asInstanceOf[Schema[Any]], name, config)
125131

126132
case Schema.Either(leftSchema, rightSchema, _) =>
127-
encodeEither(value.asInstanceOf[Either[Any, Any]], leftSchema, rightSchema, name, config)
133+
encodeEither(
134+
value.asInstanceOf[Either[Any, Any]],
135+
leftSchema.asInstanceOf[Schema[Any]],
136+
rightSchema.asInstanceOf[Schema[Any]],
137+
name,
138+
config
139+
)
128140

129141
case Schema.Tuple2(leftSchema, rightSchema, _) =>
130-
encodeTuple(value.asInstanceOf[(Any, Any)], leftSchema, rightSchema, name, config)
142+
encodeTuple(
143+
value.asInstanceOf[(Any, Any)],
144+
leftSchema.asInstanceOf[Schema[Any]],
145+
rightSchema.asInstanceOf[Schema[Any]],
146+
name,
147+
config
148+
)
131149

132150
case Schema.Transform(codec, _, g, _, _) =>
133151
g(value) match {
@@ -432,13 +450,19 @@ object XmlCodec {
432450
}
433451

434452
case Schema.Sequence(elementSchema, fromChunk, _, _, _) =>
435-
decodeSequence(nodes, elementSchema, fromChunk, config, path)
453+
decodeSequence(
454+
nodes,
455+
elementSchema.asInstanceOf[Schema[Any]],
456+
fromChunk.asInstanceOf[Chunk[Any] => A],
457+
config,
458+
path
459+
)
436460

437461
case Schema.Map(keySchema, valueSchema, _) =>
438462
decodeMap(nodes, keySchema, valueSchema, config, path)
439463

440464
case Schema.Set(elementSchema, _) =>
441-
decodeSet(nodes, elementSchema, config, path)
465+
decodeSet(nodes, elementSchema.asInstanceOf[Schema[Any]], config, path).asInstanceOf[Either[DecodeError, A]]
442466

443467
case Schema.Either(leftSchema, rightSchema, _) =>
444468
decodeEither(nodes, leftSchema, rightSchema, config, path)

zio-schema-xml/src/main/scala/zio/schema/codec/XmlSchemaCodec.scala

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import scala.xml._
77
import zio.schema.StandardType._
88
import zio.schema._
99
import zio.schema.annotation.validate
10-
import zio.schema.codec.XmlAnnotations
1110
import zio.schema.validation.Validation
1211
import zio.{ Cause, Chunk }
1312

@@ -111,7 +110,7 @@ object XmlSchemaCodec extends XmlSchemaCodec {
111110
case Schema.Sequence(elemSchema, _, _, _, _) =>
112111
collectDefinitions(elemSchema, visited)
113112
case Schema.Map(k, v, _) =>
114-
collectMapDefinitions(k, v, visited)
113+
collectMapDefinitions(k.asInstanceOf[Schema[Any]], v.asInstanceOf[Schema[Any]], visited)
115114
case Schema.Optional(inner, _) => collectDefinitions(inner, visited)
116115
case Schema.Lazy(inner) => collectDefinitions(inner(), visited)
117116
case Schema.Transform(s, _, _, _, _) => collectDefinitions(s, visited)
@@ -148,22 +147,21 @@ object XmlSchemaCodec extends XmlSchemaCodec {
148147
}
149148
}
150149

151-
private def collectEnumDefinitions(enum: Schema.Enum[_], visited: Set[String]): (List[Node], String) = {
152-
val name = s"${getRootName(enum)}Type"
150+
private def collectEnumDefinitions(`enum`: Schema.Enum[_], visited: Set[String]): (List[Node], String) = {
151+
val name = s"${getRootName(`enum`)}Type"
153152
if (visited(name)) {
154153
(Nil, name)
155154
} else {
156-
// Check if this is a simple string enumeration
157-
val isSimpleEnum = enum.cases.forall { c =>
155+
val isSimpleEnum = `enum`.cases.forall { c =>
158156
c.schema match {
159157
case Schema.Primitive(_, _) => true
160158
case r: Schema.Record[_] if r.fields.isEmpty => true
161159
case _ => false
162160
}
163161
}
164162

165-
if (isSimpleEnum && enum.cases.nonEmpty) {
166-
val enumerationNodes = enum.cases.map { c =>
163+
if (isSimpleEnum && `enum`.cases.nonEmpty) {
164+
val enumerationNodes = `enum`.cases.map { c =>
167165
elem("xs:enumeration", "value" -> c.id)
168166
}
169167
val restriction = elem(
@@ -174,7 +172,7 @@ object XmlSchemaCodec extends XmlSchemaCodec {
174172
val simpleType = elem("xs:simpleType", List("name" -> name), restriction)
175173
(List(simpleType), name)
176174
} else {
177-
val (allCaseDefs, caseElems) = enum.cases.foldLeft((List.empty[Node], List.empty[Node])) { (acc, c) =>
175+
val (allCaseDefs, caseElems) = `enum`.cases.foldLeft((List.empty[Node], List.empty[Node])) { (acc, c) =>
178176
val (defs, _) = collectDefinitions(c.schema, visited + name)
179177
val caseType = schemaTypeName(c.schema, c.id)
180178
val caseElem = elem("xs:element", "name" -> c.id, "type" -> caseType)
@@ -704,10 +702,11 @@ object XmlSchemaCodec extends XmlSchemaCodec {
704702
if (validation == Validation.succeed) schema else schema.asInstanceOf[Schema[Any]].annotate(validate(validation))
705703

706704
private def decodeEnumeration(typeName: String, enumerations: NodeSeq): Either[DecodeError, Schema[_]] = {
707-
val cases = enumerations.map { n =>
705+
val casesList = enumerations.map { n =>
708706
val v = n \@ "value"
709707
Schema.Case[String, String](v, Schema[String], _.asInstanceOf[String], identity, (s: String) => s == v)
710-
}.to(Chunk)
708+
}
709+
val cases = Chunk.fromIterable(casesList)
711710

712711
val caseSet = cases.foldRight[CaseSet.Aux[String]](CaseSet.Empty[String]()) { (c, cs) =>
713712
CaseSet.Cons(c, cs)

0 commit comments

Comments
 (0)