From 115c65671c07db3600130dd7ef9fa21c1dc6029c Mon Sep 17 00:00:00 2001 From: "a.valentinov" Date: Sun, 19 Feb 2023 17:55:43 +0600 Subject: [PATCH] More java.time instances --- .../phobos/decoding/AttributeDecoder.scala | 22 ++++++++++++++++++ .../phobos/decoding/ElementDecoder.scala | 6 +++++ .../tinkoff/phobos/decoding/TextDecoder.scala | 23 ++++++++++++++++++- .../phobos/encoding/AttributeEncoder.scala | 22 ++++++++++++++++++ .../phobos/encoding/ElementEncoder.scala | 6 +++++ .../tinkoff/phobos/encoding/TextEncoder.scala | 22 ++++++++++++++++++ 6 files changed, 100 insertions(+), 1 deletion(-) diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/AttributeDecoder.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/AttributeDecoder.scala index 233baf6..2f6bc30 100644 --- a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/AttributeDecoder.scala +++ b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/AttributeDecoder.scala @@ -1,6 +1,7 @@ package ru.tinkoff.phobos.decoding import java.time._ +import java.time.format.DateTimeFormatter import java.util.{Base64, UUID} /** Warning! This is an internal API which may change in future. Do not implement or use this trait directly unless you @@ -130,18 +131,39 @@ object AttributeDecoder extends AttributeLiteralInstances { ): Either[DecodingError, None.type] = Right(None) } + implicit val instantDecoder: AttributeDecoder[Instant] = + stringDecoder.emap(wrapException(Instant.parse)) + + def instantDecoderWithFormatter(formatter: DateTimeFormatter): AttributeDecoder[Instant] = + stringDecoder.emap(wrapException(string => Instant.from(formatter.parse(string)))) + implicit val localDateTimeDecoder: AttributeDecoder[LocalDateTime] = stringDecoder.emap(wrapException(LocalDateTime.parse)) + def localDateTimeDecoderWithFormatter(formatter: DateTimeFormatter): AttributeDecoder[LocalDateTime] = + stringDecoder.emap(wrapException(LocalDateTime.parse(_, formatter))) + implicit val zonedDateTimeDecoder: AttributeDecoder[ZonedDateTime] = stringDecoder.emap(wrapException(ZonedDateTime.parse)) + def zonedDateTimeDecoderWithFormatter(formatter: DateTimeFormatter): AttributeDecoder[ZonedDateTime] = + stringDecoder.emap(wrapException(ZonedDateTime.parse(_, formatter))) + implicit val offsetDateTimeDecoder: AttributeDecoder[OffsetDateTime] = stringDecoder.emap(wrapException(OffsetDateTime.parse)) + def offsetDateTimeDecoderWithFormatter(formatter: DateTimeFormatter): AttributeDecoder[OffsetDateTime] = + stringDecoder.emap(wrapException(OffsetDateTime.parse(_, formatter))) + implicit val localDateDecoder: AttributeDecoder[LocalDate] = stringDecoder.emap(wrapException(LocalDate.parse)) + def localDateDecoderWithFormatter(formatter: DateTimeFormatter): AttributeDecoder[LocalDate] = + stringDecoder.emap(wrapException(LocalDate.parse(_, formatter))) + implicit val localTimeDecoder: AttributeDecoder[LocalTime] = stringDecoder.emap(wrapException(LocalTime.parse)) + + def localTimeDecoderWithFormatter(formatter: DateTimeFormatter): AttributeDecoder[LocalTime] = + stringDecoder.emap(wrapException(LocalTime.parse(_, formatter))) } diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/ElementDecoder.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/ElementDecoder.scala index 67d1d3a..fb5f001 100644 --- a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/ElementDecoder.scala +++ b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/ElementDecoder.scala @@ -294,6 +294,12 @@ object ElementDecoder extends ElementLiteralInstances with DerivedElement { implicit def vectorDecoder[A](implicit decoder: ElementDecoder[A]): ElementDecoder[Vector[A]] = listDecoder[A].map(_.toVector) + implicit val instantDecoder: ElementDecoder[Instant] = + stringDecoder.emap(wrapException(Instant.parse)) + + def instantDecoderWithFormatter(formatter: DateTimeFormatter): ElementDecoder[Instant] = + stringDecoder.emap(wrapException(string => Instant.from(formatter.parse(string)))) + implicit val localDateTimeDecoder: ElementDecoder[LocalDateTime] = stringDecoder.emap(wrapException(LocalDateTime.parse)) diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/TextDecoder.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/TextDecoder.scala index 056b393..c83ca9f 100644 --- a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/TextDecoder.scala +++ b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/TextDecoder.scala @@ -2,10 +2,10 @@ package ru.tinkoff.phobos.decoding import java.time._ import java.util.{Base64, UUID} - import javax.xml.stream.XMLStreamConstants import ru.tinkoff.phobos.decoding.TextDecoder.{EMappedDecoder, MappedDecoder} +import java.time.format.DateTimeFormatter import scala.annotation.tailrec /** Warning! This is a complicated internal API which may change in future. Do not implement or use this trait directly @@ -151,18 +151,39 @@ object TextDecoder extends TextLiteralInstances { implicit val base64Decoder: TextDecoder[Array[Byte]] = stringDecoder.emap(wrapException(Base64.getDecoder.decode)) + implicit val instantDecoder: TextDecoder[Instant] = + stringDecoder.emap(wrapException(Instant.parse)) + + def instantDecoderWithFormatter(formatter: DateTimeFormatter): TextDecoder[Instant] = + stringDecoder.emap(wrapException(string => Instant.from(formatter.parse(string)))) + implicit val localDateTimeDecoder: TextDecoder[LocalDateTime] = stringDecoder.emap(wrapException(LocalDateTime.parse)) + def localDateTimeDecoderWithFormatter(formatter: DateTimeFormatter): TextDecoder[LocalDateTime] = + stringDecoder.emap(wrapException(LocalDateTime.parse(_, formatter))) + implicit val zonedDateTimeDecoder: TextDecoder[ZonedDateTime] = stringDecoder.emap(wrapException(ZonedDateTime.parse)) + def zonedDateTimeDecoderWithFormatter(formatter: DateTimeFormatter): TextDecoder[ZonedDateTime] = + stringDecoder.emap(wrapException(ZonedDateTime.parse(_, formatter))) + implicit val offsetDateTimeDecoder: TextDecoder[OffsetDateTime] = stringDecoder.emap(wrapException(OffsetDateTime.parse)) + def offsetDateTimeDecoderWithFormatter(formatter: DateTimeFormatter): TextDecoder[OffsetDateTime] = + stringDecoder.emap(wrapException(OffsetDateTime.parse(_, formatter))) + implicit val localDateDecoder: TextDecoder[LocalDate] = stringDecoder.emap(wrapException(LocalDate.parse)) + def localDateDecoderWithFormatter(formatter: DateTimeFormatter): TextDecoder[LocalDate] = + stringDecoder.emap(wrapException(LocalDate.parse(_, formatter))) + implicit val localTimeDecoder: TextDecoder[LocalTime] = stringDecoder.emap(wrapException(LocalTime.parse)) + + def localTimeDecoderWithFormatter(formatter: DateTimeFormatter): TextDecoder[LocalTime] = + stringDecoder.emap(wrapException(LocalTime.parse(_, formatter))) } diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/AttributeEncoder.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/AttributeEncoder.scala index ad5f6e6..0a8619f 100644 --- a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/AttributeEncoder.scala +++ b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/AttributeEncoder.scala @@ -1,6 +1,7 @@ package ru.tinkoff.phobos.encoding import java.time._ +import java.time.format.DateTimeFormatter import java.util.{Base64, UUID} /** Warning! This is an internal API which may change in future. Do not implement or use this trait directly unless you @@ -80,18 +81,39 @@ object AttributeEncoder extends AttributeLiteralInstances { implicit val noneEncoder: AttributeEncoder[None.type] = unitEncoder.contramap(_ => ()) + implicit val instantEncoder: AttributeEncoder[Instant] = + stringEncoder.contramap(_.toString) + + def instantEncoderWithFormatter(formatter: DateTimeFormatter): AttributeEncoder[Instant] = + stringEncoder.contramap(formatter.format) + implicit val localDateTimeEncoder: AttributeEncoder[LocalDateTime] = stringEncoder.contramap(_.toString) + def localDateTimeEncoderWithFormatter(formatter: DateTimeFormatter): AttributeEncoder[LocalDateTime] = + stringEncoder.contramap(_.format(formatter)) + implicit val zonedDateTimeEncoder: AttributeEncoder[ZonedDateTime] = stringEncoder.contramap(_.toString) + def zonedDateTimeEncoderWithFormatter(formatter: DateTimeFormatter): AttributeEncoder[ZonedDateTime] = + stringEncoder.contramap(_.format(formatter)) + implicit val offsetDateTimeEncoder: AttributeEncoder[OffsetDateTime] = stringEncoder.contramap(_.toString) + def offsetDateTimeEncoderWithFormatter(formatter: DateTimeFormatter): AttributeEncoder[OffsetDateTime] = + stringEncoder.contramap(_.format(formatter)) + implicit val localDateEncoder: AttributeEncoder[LocalDate] = stringEncoder.contramap(_.toString) + def localDateEncoderWithFormatter(formatter: DateTimeFormatter): AttributeEncoder[LocalDate] = + stringEncoder.contramap(_.format(formatter)) + implicit val localTimeEncoder: AttributeEncoder[LocalTime] = stringEncoder.contramap(_.toString) + + def localTimeEncoderWithFormatter(formatter: DateTimeFormatter): AttributeEncoder[LocalTime] = + stringEncoder.contramap(_.format(formatter)) } diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/ElementEncoder.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/ElementEncoder.scala index 649369b..f575090 100644 --- a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/ElementEncoder.scala +++ b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/ElementEncoder.scala @@ -152,6 +152,12 @@ object ElementEncoder extends ElementLiteralInstances with DerivedElement { implicit def vectorEncoder[A](implicit encoder: ElementEncoder[A]): ElementEncoder[Vector[A]] = iteratorEncoder[A].contramap(_.iterator) + implicit val instantEncoder: ElementEncoder[Instant] = + stringEncoder.contramap(_.toString) + + def instantEncoderWithFormatter(formatter: DateTimeFormatter): ElementEncoder[Instant] = + stringEncoder.contramap(formatter.format) + implicit val localDateTimeEncoder: ElementEncoder[LocalDateTime] = stringEncoder.contramap(_.toString) diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/TextEncoder.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/TextEncoder.scala index b9c2a08..4eb1a5b 100644 --- a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/TextEncoder.scala +++ b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/TextEncoder.scala @@ -1,6 +1,7 @@ package ru.tinkoff.phobos.encoding import java.time._ +import java.time.format.DateTimeFormatter import java.util.{Base64, UUID} /** Use XmlEncoder for encoding XML documents. @@ -61,18 +62,39 @@ object TextEncoder extends TextLiteralInstances { implicit val base64Encoder: TextEncoder[Array[Byte]] = stringEncoder.contramap(Base64.getEncoder.encodeToString) + implicit val instantEncoder: TextEncoder[Instant] = + stringEncoder.contramap(_.toString) + + def instantEncoderWithFormatter(formatter: DateTimeFormatter): TextEncoder[Instant] = + stringEncoder.contramap(formatter.format) + implicit val localDateTimeEncoder: TextEncoder[LocalDateTime] = stringEncoder.contramap(_.toString) + def localDateTimeEncoderWithFormatter(formatter: DateTimeFormatter): TextEncoder[LocalDateTime] = + stringEncoder.contramap(_.format(formatter)) + implicit val zonedDateTimeEncoder: TextEncoder[ZonedDateTime] = stringEncoder.contramap(_.toString) + def zonedDateTimeEncoderWithFormatter(formatter: DateTimeFormatter): TextEncoder[ZonedDateTime] = + stringEncoder.contramap(_.format(formatter)) + implicit val offsetDateTimeEncoder: TextEncoder[OffsetDateTime] = stringEncoder.contramap(_.toString) + def offsetDateTimeEncoderWithFormatter(formatter: DateTimeFormatter): TextEncoder[OffsetDateTime] = + stringEncoder.contramap(_.format(formatter)) + implicit val localDateEncoder: TextEncoder[LocalDate] = stringEncoder.contramap(_.toString) + def localDateEncoderWithFormatter(formatter: DateTimeFormatter): TextEncoder[LocalDate] = + stringEncoder.contramap(_.format(formatter)) + implicit val localTimeEncoder: TextEncoder[LocalTime] = stringEncoder.contramap(_.toString) + + def localTimeEncoderWithFormatter(formatter: DateTimeFormatter): TextEncoder[LocalTime] = + stringEncoder.contramap(_.format(formatter)) }