Skip to content

feat: add XML Codec module (#754)#1025

Open
Abu1982 wants to merge 4 commits intozio:mainfrom
Abu1982:fix-754
Open

feat: add XML Codec module (#754)#1025
Abu1982 wants to merge 4 commits intozio:mainfrom
Abu1982:fix-754

Conversation

@Abu1982
Copy link

@Abu1982 Abu1982 commented Mar 5, 2026

XML Codec for ZIO Schema

Closes #754

Summary

This PR adds a new zio-schema-xml module that provides XML encoding and decoding support for ZIO Schema, following the same patterns as existing codecs (JSON, MessagePack, Protobuf, etc.).

Implementation

Module structure:

  • XmlCodec.scala - Entry point providing BinaryCodec[A] instances via implicit xmlCodec[A]
  • XmlEncoder.scala - Encodes ZIO Schema values to XML strings with proper escaping
  • XmlDecoder.scala - Decodes XML strings back to ZIO Schema values using scala-xml
  • XmlCodecSpec.scala - Comprehensive roundtrip tests

Supported types:

  • All primitive types (String, Int, Long, Boolean, Double, Float, BigDecimal, BigInteger, UUID, Char, Binary/Base64)
  • All temporal types (LocalDate, LocalTime, LocalDateTime, Instant, Duration, ZonedDateTime, OffsetDateTime, OffsetTime, Period, Year, YearMonth, MonthDay, DayOfWeek, Month, ZoneId, ZoneOffset)
  • Currency type
  • Case classes (CaseClass0 through CaseClass22 via generic Record API)
  • Sealed traits / enums (Enum1 through EnumN)
  • Collections (List, Set, Map, Sequence)
  • Optional values
  • Either and Fallback
  • Tuples
  • Nested/recursive types via Schema.Lazy
  • GenericRecord
  • DynamicValue
  • Transform schemas

XML format:

  • Records encode fields as child elements: <root><name>Alice</name><age>30</age></root>
  • Sequences use <item> elements: <root><item>1</item><item>2</item></root>
  • Maps use <entry><key>k</key><value>v</value></entry> structure
  • Enums use a type attribute: <root type="Red"><value/></root>
  • Optional None renders as self-closing: <field/>
  • XML declaration included: <?xml version="1.0" encoding="UTF-8"?>
  • Special characters properly escaped (&amp;, &lt;, &gt;, &quot;, &apos;)

Dependencies:

  • org.scala-lang.modules:scala-xml:2.3.0 (JVM only, like MsgPack/Thrift/Avro/Bson modules)

Testing

Roundtrip tests covering primitives, case classes, nested structures, collections, optionals, either, enums, tuples, temporal types, and XML special character handling.

@Abu1982 Abu1982 requested a review from a team as a code owner March 5, 2026 11:08
@hriszc
Copy link

hriszc commented Mar 8, 2026

I reviewed the current XML codec implementation and found two round-trip edge cases that look merge-blocking:

  • empty optional payloads like Some("") and Some(Nil) can collapse to None
  • string decoding trims surrounding whitespace, so some values do not round-trip exactly

I prepared a focused follow-up patch here:

What it changes:

  • encodes Option values explicitly with a <value> wrapper and nil="true" for None
  • keeps a compatibility path for previously encoded optional payloads
  • preserves leading/trailing whitespace for String and Char
  • adds regression tests for Some(""), Some(Nil), and strings with surrounding whitespace
  • wires zioSchemaXml into the standard JVM test alias/docs aggregation

I did not run the JVM suite locally because the environment I used did not have a usable Java runtime, so this should still be validated in CI/local JVM once applied.

@hriszc
Copy link

hriszc commented Mar 10, 2026

Follow-up on the XML codec thread: the patch comment I posted earlier is still the intended delta from my side, focused on Option encoding/decoding stability, whitespace preservation, and wiring the XML module into the standard test path.\n\nThe PR itself is green. If maintainers are open to folding those fixes into this branch, I can keep iterating from that direction rather than opening a duplicate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

XML Codec

2 participants