LINUX.ORG.RU

Представление типов XML-RPC в Scala

 , ,


0

1

Допустим, нам нужно написать сериализатор значений для XML-RPC. Спека определяет правила сериализации для примитивов. С этим проблем нет. Заводим трейт

CanRepresentAs[-From, +To]
где определяем метод
def convert(x: From): To
Далее для каждого примитивного типа заводим по implicit занчению типа CanRepresentAs[XXX, scala.xml.Node] с нужной реализацией. Эти значения затем подтягиваются в качестве implicit-параметров в те функции, которые нуждаются в сериализации. С примитивами разобрались, переходим к массивам и структурам. Массив тоже сериализуется очень просто, мы определяем implicit-функцию
implicit def seqAsXML[T](implicit sr: CanRepresentAs[T, scala.xml.Node]): CanRepresentAs[Seq[T], scala.xml.Node]
и дальше всё происходит по той же схеме. А вот со структурами дело обстоит сложнее ввиду их разнородности. Мы не можем представить структуру как Map, потому что её поля имеют разный тип. Логично было бы определить правила сериализации для любого типа, и тогда структуру составляли бы поля произвольно взятого объекта, но из-за контрвариантности CanRepresentAs по типу From это поломает сериализацию примитивов, так как возникнет конфликт при резолюции неявных параметров.

Сейчас я вижу такие варианты решения:

  1. Определить тип-маркер XMLRPCStruct и правила сериализации только для этого типа. Но это какой-то жабизм и вообще говнодизайн.
  2. Генерировать неявные значения макросами. Это ведёт к усложнению структуры проекта.
  3. Сделать аналог CanRepresentAs, только с перламутровыми пуговицами инвариантный. Это дублирование кода. Поправка: это бред.

Какие ещё варианты может предложить лор-коммунити?

★★★

Последнее исправление: Zenom (всего исправлений: 1)

сделай обобщенный сериализатор Map/Seq который будет неявно использовать сериализатор для своих элементов

maxcom ★★★★★
()
Ответ на: комментарий от maxcom

С Seq так и сделано. А с Map не выйдет, потому что Map не отражает типы значений в своей сигнатуре. Т. е. если для представления структуры использовать Map[String, Any], то надо иметь сериализатор для Any.

Zenom ★★★
() автор топика
Ответ на: комментарий от maxcom

Я хочу сериализовать структуру с полями name: String и age: Int. Какая сигнатура должна быть у Map чтобы её представить?

Zenom ★★★
() автор топика
Ответ на: комментарий от maxcom

используй case class с двумя полями

Вот вообще шикарный совет! Весь вопрос в том, как именно его использовать.

Или record из shapeless.

Ограничивает потенциальных пользователей в выборе, но как вариант катит.

По результатам треда склоняюсь к implicit макросам.

Zenom ★★★
() автор топика
Ответ на: комментарий от Zenom

Вот вообще шикарный совет! Весь вопрос в том, как именно его использовать.

Макросом разобрать на части.

maxcom ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.