diff --git a/README.md b/README.md
index 817bd1e..107022a 100644
--- a/README.md
+++ b/README.md
@@ -49,10 +49,10 @@ val journey =
arrival = TravelPoint("Germany", "Munich")
)
-val xml: String = XmlEncoder[Journey].encode(journey)
+val xml = XmlEncoder[Journey].encode(journey)
println(xml)
-val decodedJourney = XmlDecoder[Journey].decode(xml)
+val decodedJourney = xml.flatMap(XmlDecoder[Journey].decode(_))
println(decodedJourney)
assert(Right(journey) == decodedJourney)
diff --git a/build.sbt b/build.sbt
index 872669a..29b3397 100644
--- a/build.sbt
+++ b/build.sbt
@@ -2,7 +2,7 @@
ThisBuild / name := "phobos"
-ThisBuild / scalaVersion := "3.1.2"
+ThisBuild / scalaVersion := "3.2.1"
lazy val commonDependencies =
libraryDependencies ++=
diff --git a/modules/akka-http/src/main/scala/ru/tinkoff/phobos/akka_http/marshalling/application.scala b/modules/akka-http/src/main/scala/ru/tinkoff/phobos/akka_http/marshalling/application.scala
index 5ec6ed6..53e28f3 100644
--- a/modules/akka-http/src/main/scala/ru/tinkoff/phobos/akka_http/marshalling/application.scala
+++ b/modules/akka-http/src/main/scala/ru/tinkoff/phobos/akka_http/marshalling/application.scala
@@ -9,7 +9,7 @@ import ru.tinkoff.phobos.encoding.XmlEncoder
object application {
implicit def soapApplicationXmlMarshaller[T](implicit encoder: XmlEncoder[T]): ToEntityMarshaller[T] =
Marshaller.withFixedContentType(MediaTypes.`application/xml` withCharset HttpCharsets.`UTF-8`) { body =>
- HttpEntity(MediaTypes.`application/xml` withCharset HttpCharsets.`UTF-8`, encoder.encode(body))
+ HttpEntity(MediaTypes.`application/xml` withCharset HttpCharsets.`UTF-8`, encoder.encodeUnsafe(body))
}
implicit def soapApplicationXmlUnmarshaller[T](implicit decoder: XmlDecoder[T]): FromEntityUnmarshaller[T] =
diff --git a/modules/akka-http/src/main/scala/ru/tinkoff/phobos/akka_http/marshalling/text.scala b/modules/akka-http/src/main/scala/ru/tinkoff/phobos/akka_http/marshalling/text.scala
index b9aeed6..31070e9 100644
--- a/modules/akka-http/src/main/scala/ru/tinkoff/phobos/akka_http/marshalling/text.scala
+++ b/modules/akka-http/src/main/scala/ru/tinkoff/phobos/akka_http/marshalling/text.scala
@@ -10,7 +10,7 @@ import ru.tinkoff.phobos.encoding.XmlEncoder
object text {
implicit def soapTextXmlMarshaller[T](implicit encoder: XmlEncoder[T]): ToEntityMarshaller[T] =
Marshaller.withFixedContentType(`text/xml(UTF-8)`) { body =>
- HttpEntity(`text/xml(UTF-8)`, encoder.encode(body))
+ HttpEntity(`text/xml(UTF-8)`, encoder.encodeUnsafe(body))
}
implicit def soapTextXmlUnmarshaller[T](implicit decoder: XmlDecoder[T]): FromEntityUnmarshaller[T] =
diff --git a/modules/akka-stream/src/main/scala/ru/tinkoff/phobos/ops/AkkaStreamOps.scala b/modules/akka-stream/src/main/scala/ru/tinkoff/phobos/ops/AkkaStreamOps.scala
index 5dc299a..5490d22 100644
--- a/modules/akka-stream/src/main/scala/ru/tinkoff/phobos/ops/AkkaStreamOps.scala
+++ b/modules/akka-stream/src/main/scala/ru/tinkoff/phobos/ops/AkkaStreamOps.scala
@@ -39,7 +39,7 @@ private[phobos] trait AkkaStreamOps {
}
.map {
case None =>
- throw DecodingError("Got an internal error while decoding byte stream", Nil)
+ throw DecodingError("Got an internal error while decoding byte stream", Nil, None)
case Some(SinkDecoderState(_, cursor, elementDecoder)) =>
elementDecoder.result(cursor.history)
diff --git a/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/CodecProperties.scala b/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/CodecProperties.scala
index 7e3a10c..bbcc292 100644
--- a/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/CodecProperties.scala
+++ b/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/CodecProperties.scala
@@ -13,15 +13,12 @@ class CodecProperties extends Properties("Ast codecs") {
private val decoder = XmlDecoder.fromElementDecoder[XmlEntry]("test")
property("decode(encode(ast)) === ast") = forAll { entry: XmlEntry =>
- decoder.decode(
- encoder.encode(entry),
- ) == Right(entry)
+ encoder.encode(entry).flatMap(decoder.decode(_)) == Right(entry)
}
property("encode(decode(xmlAst)) === xmlAst") = forAll { entry: XmlEntry =>
val encoded = encoder.encode(entry)
-
- decoder.decode(encoded).map(encoder.encode(_)) == Right(encoded)
+ encoded.flatMap(decoder.decode(_)).map(encoder.encode(_)) == Right(encoded)
}
}
diff --git a/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/XmlEntryElementDecoderTest.scala b/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/XmlEntryElementDecoderTest.scala
index c3e2386..755b0d4 100644
--- a/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/XmlEntryElementDecoderTest.scala
+++ b/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/XmlEntryElementDecoderTest.scala
@@ -60,15 +60,9 @@ class XmlEntryElementDecoderTest extends AnyWordSpec with Matchers with DiffShou
val encoded = ru.tinkoff.phobos.encoding.XmlEncoder.fromElementEncoder[XmlEntry]("ast").encode(n)
- val result = XmlDecoder
- .fromElementDecoder[XmlEntry]("ast")
- .decode(
- encoded,
- )
+ val result = encoded.flatMap(XmlDecoder.fromElementDecoder[XmlEntry]("ast").decode(_))
- result.map(util.AstTransformer.sortNodeValues) shouldMatchTo (
- util.AstTransformer.sortNodeValues(n).asRight[DecodingError]
- )
+ assert(result.map(util.AstTransformer.sortNodeValues) == Right(util.AstTransformer.sortNodeValues(n)))
}
}
}
diff --git a/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/XmlEntryElementEncoderTest.scala b/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/XmlEntryElementEncoderTest.scala
index 37d952a..7151db2 100644
--- a/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/XmlEntryElementEncoderTest.scala
+++ b/modules/ast/src/test/scala/ru/tinkoff/phobos/ast/XmlEntryElementEncoderTest.scala
@@ -16,7 +16,7 @@ class XmlEntryElementEncoderTest extends AnyWordSpec with DiffShouldMatcher with
.fromElementEncoder[XmlEntry]("ast")
.encode(ast)
- assert(result == """bazz""")
+ assert(result == Right("""bazz"""))
}
"encodes nested Xml ast correctly" in {
case object tinkoff {
@@ -46,7 +46,9 @@ class XmlEntryElementEncoderTest extends AnyWordSpec with DiffShouldMatcher with
.encode(ast)
assert(
- result == """bazz11111111111111111111111111122.130.13""",
+ result == Right(
+ """bazz11111111111111111111111111122.130.13""",
+ ),
)
}
}
diff --git a/modules/cats/src/main/scala/ru/tinkoff/phobos/catsInstances.scala b/modules/cats/src/main/scala/ru/tinkoff/phobos/catsInstances.scala
index 04e0a46..6aa3358 100644
--- a/modules/cats/src/main/scala/ru/tinkoff/phobos/catsInstances.scala
+++ b/modules/cats/src/main/scala/ru/tinkoff/phobos/catsInstances.scala
@@ -62,21 +62,25 @@ object catsInstances {
listDecoder[A].emap((history, list) =>
NonEmptyList
.fromList(list)
- .fold[Either[DecodingError, NonEmptyList[A]]](Left(DecodingError("List is empty", history)))(Right.apply),
+ .fold[Either[DecodingError, NonEmptyList[A]]](Left(DecodingError("List is empty", history, None)))(Right.apply),
)
implicit def nonEmptyVectorElementDecoder[A](implicit decoder: ElementDecoder[A]): ElementDecoder[NonEmptyVector[A]] =
vectorDecoder[A].emap((history, vector) =>
NonEmptyVector
.fromVector(vector)
- .fold[Either[DecodingError, NonEmptyVector[A]]](Left(DecodingError("Vector is empty", history)))(Right.apply),
+ .fold[Either[DecodingError, NonEmptyVector[A]]](Left(DecodingError("Vector is empty", history, None)))(
+ Right.apply,
+ ),
)
implicit def nonEmptyChainElementDecoder[A](implicit decoder: ElementDecoder[A]): ElementDecoder[NonEmptyChain[A]] =
chainElementDecoder[A].emap((history, chain) =>
NonEmptyChain
.fromChain(chain)
- .fold[Either[DecodingError, NonEmptyChain[A]]](Left(DecodingError("Chain is empty", history)))(Right.apply),
+ .fold[Either[DecodingError, NonEmptyChain[A]]](Left(DecodingError("Chain is empty", history, None)))(
+ Right.apply,
+ ),
)
implicit class XmlDecoderCatsOps[A](val xmlDecoder: XmlDecoder[A]) extends AnyVal {
diff --git a/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/AttributeLiteralInstances.scala b/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/AttributeLiteralInstances.scala
index 2dd036c..ccf8440 100644
--- a/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/AttributeLiteralInstances.scala
+++ b/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/AttributeLiteralInstances.scala
@@ -8,6 +8,7 @@ private[decoding] trait AttributeLiteralInstances {
decoder
.emap((history, a) =>
if (a == valueOfL.value) Right(valueOfL.value)
- else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history)),
+ else
+ Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history, None)),
)
}
diff --git a/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/ElementLiteralInstances.scala b/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/ElementLiteralInstances.scala
index ef4e2f1..5e8bfa9 100644
--- a/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/ElementLiteralInstances.scala
+++ b/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/ElementLiteralInstances.scala
@@ -5,6 +5,6 @@ private[decoding] trait ElementLiteralInstances {
decoder
.emap((history, a) =>
if (a == valueOfL.value) Right(valueOfL.value)
- else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history)),
+ else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history, None)),
)
}
diff --git a/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/TextLiteralInstances.scala b/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/TextLiteralInstances.scala
index 2466d87..f4f1fc5 100644
--- a/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/TextLiteralInstances.scala
+++ b/modules/core/src/main/scala-2.13/ru/tinkoff/phobos/decoding/TextLiteralInstances.scala
@@ -5,6 +5,7 @@ private[decoding] trait TextLiteralInstances {
decoder
.emap((history, a) =>
if (a == valueOfL.value) Right(valueOfL.value)
- else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history)),
+ else
+ Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history, None)),
)
}
diff --git a/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/AttributeLiteralInstances.scala b/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/AttributeLiteralInstances.scala
index 2dd036c..d0fc926 100644
--- a/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/AttributeLiteralInstances.scala
+++ b/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/AttributeLiteralInstances.scala
@@ -8,6 +8,6 @@ private[decoding] trait AttributeLiteralInstances {
decoder
.emap((history, a) =>
if (a == valueOfL.value) Right(valueOfL.value)
- else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history)),
+ else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history, None)),
)
}
diff --git a/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/ElementLiteralInstances.scala b/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/ElementLiteralInstances.scala
index ef4e2f1..5e8bfa9 100644
--- a/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/ElementLiteralInstances.scala
+++ b/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/ElementLiteralInstances.scala
@@ -5,6 +5,6 @@ private[decoding] trait ElementLiteralInstances {
decoder
.emap((history, a) =>
if (a == valueOfL.value) Right(valueOfL.value)
- else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history)),
+ else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history, None)),
)
}
diff --git a/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/TextLiteralInstances.scala b/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/TextLiteralInstances.scala
index 2466d87..32a1c61 100644
--- a/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/TextLiteralInstances.scala
+++ b/modules/core/src/main/scala-3/ru/tinkoff/phobos/decoding/TextLiteralInstances.scala
@@ -5,6 +5,6 @@ private[decoding] trait TextLiteralInstances {
decoder
.emap((history, a) =>
if (a == valueOfL.value) Right(valueOfL.value)
- else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history)),
+ else Left(DecodingError(s"Failed to decode literal type. Expected: ${valueOfL.value}, actual: $a", history, None)),
)
}
diff --git a/modules/core/src/main/scala-3/ru/tinkoff/phobos/derivation/decoder.scala b/modules/core/src/main/scala-3/ru/tinkoff/phobos/derivation/decoder.scala
index 47ae111..70c570c 100644
--- a/modules/core/src/main/scala-3/ru/tinkoff/phobos/derivation/decoder.scala
+++ b/modules/core/src/main/scala-3/ru/tinkoff/phobos/derivation/decoder.scala
@@ -228,7 +228,7 @@ object decoder {
$currentFieldStates
.getOrElse(
${Expr(field.localName)},
- Left(DecodingError(s"Attribute '${${field.xmlName}}' is missing or invalid", $c.history))
+ Left(DecodingError(s"Attribute '${${field.xmlName}}' is missing or invalid", $c.history, None))
)
.asInstanceOf[Either[DecodingError, t]]
.flatMap { ${f.asExprOf[t => Either[DecodingError, T]]} }
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..137783f 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
@@ -64,7 +64,7 @@ object AttributeDecoder extends AttributeLiteralInstances {
string match {
case "true" | "1" => Right(true)
case "false" | "0" => Right(false)
- case str => Left(DecodingError(s"Value `$str` is not `true` or `false`", history))
+ case str => Left(DecodingError(s"Value `$str` is not `true` or `false`", history, None))
},
)
@@ -73,7 +73,7 @@ object AttributeDecoder extends AttributeLiteralInstances {
implicit val charDecoder: AttributeDecoder[Char] =
stringDecoder.emap((history, string) => {
if (string.length != 1) {
- Left(DecodingError("Value too long for char", history))
+ Left(DecodingError("Value too long for char", history, None))
} else {
Right(string.head)
}
diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/Cursor.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/Cursor.scala
index 0c6a08a..b9a3c5e 100644
--- a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/Cursor.scala
+++ b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/Cursor.scala
@@ -32,7 +32,7 @@ class Cursor(private val sr: XmlStreamReader) {
def hasNext: Boolean = sr.hasNext
def history: List[String] = historyStack
- def error(text: String): DecodingError = DecodingError(text, historyStack)
+ def error(text: String): DecodingError = DecodingError(text, historyStack, None)
var scopeDefaultNamespaceStack: List[String] = Nil
def setScopeDefaultNamespace(uri: String): Unit = {
diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/DecodingError.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/DecodingError.scala
index 2fdca90..e453a82 100644
--- a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/DecodingError.scala
+++ b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/DecodingError.scala
@@ -1,6 +1,7 @@
package ru.tinkoff.phobos.decoding
-case class DecodingError(text: String, history: List[String]) extends Exception {
+case class DecodingError(text: String, history: List[String], cause: Option[Throwable])
+ extends Exception(cause.orNull) {
override def getMessage: String = {
val trace = if (history.nonEmpty) {
history.mkString("\tIn element '", "'\n\t\tin element '", "'")
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..d7b241e 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
@@ -58,8 +58,8 @@ object ElementDecoder extends ElementLiteralInstances with DerivedElement {
def decodingNotCompleteError(history: List[String]): DecodingError =
history match {
- case element :: others => DecodingError(s"Element '$element' is missing or invalid", others)
- case Nil => DecodingError("Root element is missing or invalid", Nil)
+ case element :: others => DecodingError(s"Element '$element' is missing or invalid", others, None)
+ case Nil => DecodingError("Root element is missing or invalid", Nil, None)
}
final class MappedDecoder[A, B](fa: ElementDecoder[A], f: A => B) extends ElementDecoder[B] {
@@ -161,7 +161,7 @@ object ElementDecoder extends ElementLiteralInstances with DerivedElement {
string match {
case "true" | "1" => Right(true)
case "false" | "0" => Right(false)
- case str => Left(DecodingError(s"Value `$str` is not `true` or `false`", history))
+ case str => Left(DecodingError(s"Value `$str` is not `true` or `false`", history, None))
},
)
@@ -170,7 +170,7 @@ object ElementDecoder extends ElementLiteralInstances with DerivedElement {
implicit val charDecoder: ElementDecoder[Char] =
stringDecoder.emap((history, string) => {
if (string.length != 1) {
- Left(DecodingError("Value too long for char", history))
+ Left(DecodingError("Value too long for char", history, None))
} else {
Right(string.head)
}
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..f87abab 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
@@ -113,7 +113,7 @@ object TextDecoder extends TextLiteralInstances {
string match {
case "true" | "1" => Right(true)
case "false" | "0" => Right(false)
- case str => Left(DecodingError(s"Value `$str` is not `true` or `false`", history))
+ case str => Left(DecodingError(s"Value `$str` is not `true` or `false`", history, None))
},
)
@@ -122,7 +122,7 @@ object TextDecoder extends TextLiteralInstances {
implicit val charDecoder: TextDecoder[Char] =
stringDecoder.emap((history, string) => {
if (string.length != 1) {
- Left(DecodingError("Value too long for char", history))
+ Left(DecodingError("Value too long for char", history, None))
} else {
Right(string.head)
}
diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/XmlDecoder.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/XmlDecoder.scala
index cdfca74..8dc3637 100644
--- a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/XmlDecoder.scala
+++ b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/XmlDecoder.scala
@@ -1,7 +1,7 @@
package ru.tinkoff.phobos.decoding
import javax.xml.stream.XMLStreamConstants
-import com.fasterxml.aalto.{AsyncByteArrayFeeder, WFCException}
+import com.fasterxml.aalto.AsyncByteArrayFeeder
import com.fasterxml.aalto.async.{AsyncByteArrayScanner, AsyncStreamReaderImpl}
import com.fasterxml.aalto.stax.InputFactoryImpl
import ru.tinkoff.phobos.Namespace
@@ -42,8 +42,8 @@ trait XmlDecoder[A] extends XmlDecoderIterable[A] {
.decodeAsElement(cursor, localname, namespaceuri)
.result(cursor.history)
} catch {
- case e: WFCException =>
- Left(DecodingError(e.getMessage, cursor.history))
+ case e: Throwable =>
+ Left(DecodingError(Option(e.getMessage).getOrElse("No message provided"), cursor.history, Some(e)))
}
}
diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/package.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/package.scala
index 3cc949a..653ad56 100644
--- a/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/package.scala
+++ b/modules/core/src/main/scala/ru/tinkoff/phobos/decoding/package.scala
@@ -10,7 +10,8 @@ package object decoding {
private[decoding] def wrapException[A](f: String => A) =
(history: List[String], string: String) =>
Try(f(string)) match {
- case Failure(exception) => Left(DecodingError(exception.getMessage, history))
- case Success(a) => Right(a)
+ case Failure(exception) =>
+ Left(DecodingError(Option(exception.getMessage).getOrElse("No text provided"), history, Some(exception)))
+ case Success(a) => Right(a)
}
}
diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/EncodingError.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/EncodingError.scala
new file mode 100644
index 0000000..2710f60
--- /dev/null
+++ b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/EncodingError.scala
@@ -0,0 +1,5 @@
+package ru.tinkoff.phobos.encoding
+
+case class EncodingError(text: String, cause: Option[Throwable] = None) extends Exception(text, cause.orNull) {
+ override def getMessage: String = s"Error while decoding XML: $text"
+}
diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/PhobosStreamWriter.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/PhobosStreamWriter.scala
index 5fa9e91..f72031c 100644
--- a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/PhobosStreamWriter.scala
+++ b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/PhobosStreamWriter.scala
@@ -1,7 +1,6 @@
package ru.tinkoff.phobos.encoding
import java.math.BigInteger
-
import javax.xml.namespace.{NamespaceContext, QName}
import javax.xml.stream.XMLStreamException
import org.codehaus.stax2.typed.Base64Variant
@@ -9,7 +8,13 @@ import org.codehaus.stax2.{XMLStreamLocation2, XMLStreamReader2, XMLStreamWriter
import org.codehaus.stax2.validation.{ValidationProblemHandler, XMLValidationSchema, XMLValidator}
import PhobosStreamWriter.prefixBase
-final class PhobosStreamWriter(sw: XMLStreamWriter2) extends XMLStreamWriter2 {
+/** [[PhobosStreamWriter]] implements most methods of [[XMLStreamWriter2]], but it does not extends [[XMLStreamWriter2]]
+ *
+ * Unlike [[XMLStreamWriter2]], [[PhobosStreamWriter]] does not throw any exceptions if it is used to write invalid
+ * characters. Such characters are simply filtered out. However, [[PhobosStreamWriter]] can still throw exceptions if
+ * it is used to write invalid attribute or element names or namespaces with invalid characters.
+ */
+final class PhobosStreamWriter(sw: XMLStreamWriter2) {
private var discriminatorLocalName: Option[String] = None
private var discriminatorNamespace: Option[String] = None
@@ -49,9 +54,6 @@ final class PhobosStreamWriter(sw: XMLStreamWriter2) extends XMLStreamWriter2 {
def getEncoding: String =
sw.getEncoding
- def writeCData(text: Array[Char], start: Int, len: Int): Unit =
- sw.writeCData(text, start, len)
-
def writeDTD(rootName: String, systemId: String, publicId: String, internalSubset: String): Unit =
sw.writeDTD(rootName, systemId, publicId, internalSubset)
@@ -62,19 +64,10 @@ final class PhobosStreamWriter(sw: XMLStreamWriter2) extends XMLStreamWriter2 {
sw.writeStartDocument(version, encoding, standAlone)
def writeSpace(text: String): Unit =
- sw.writeSpace(text)
-
- def writeSpace(text: Array[Char], offset: Int, length: Int): Unit =
- sw.writeSpace(text, offset, length)
+ sw.writeSpace(text.filter(_.isWhitespace))
def writeRaw(text: String): Unit =
- sw.writeRaw(text)
-
- def writeRaw(text: String, offset: Int, length: Int): Unit =
- sw.writeRaw(text, offset, length)
-
- def writeRaw(text: Array[Char], offset: Int, length: Int): Unit =
- sw.writeRaw(text, offset, length)
+ sw.writeRaw(filterXmlText(text))
def copyEventFromReader(r: XMLStreamReader2, preserveEventData: Boolean): Unit =
sw.copyEventFromReader(r, preserveEventData)
@@ -226,13 +219,13 @@ final class PhobosStreamWriter(sw: XMLStreamWriter2) extends XMLStreamWriter2 {
sw.flush()
def writeAttribute(localName: String, value: String): Unit =
- sw.writeAttribute(localName, value)
+ sw.writeAttribute(localName, filterXmlText(value))
def writeAttribute(prefix: String, namespaceURI: String, localName: String, value: String): Unit =
- sw.writeAttribute(prefix, namespaceURI, localName, value)
+ sw.writeAttribute(prefix, namespaceURI, localName, filterXmlText(value))
def writeAttribute(namespaceURI: String, localName: String, value: String): Unit =
- sw.writeAttribute(namespaceURI, localName, value)
+ sw.writeAttribute(namespaceURI, localName, filterXmlText(value))
def writeNamespace(prefix: String, namespaceURI: String): Unit =
sw.writeNamespace(prefix, namespaceURI)
@@ -264,7 +257,7 @@ final class PhobosStreamWriter(sw: XMLStreamWriter2) extends XMLStreamWriter2 {
sw.writeDefaultNamespace(namespaceURI)
def writeComment(data: String): Unit =
- sw.writeComment(data)
+ sw.writeComment(filterXmlText(data))
def writeProcessingInstruction(target: String): Unit =
sw.writeProcessingInstruction(target)
@@ -273,7 +266,7 @@ final class PhobosStreamWriter(sw: XMLStreamWriter2) extends XMLStreamWriter2 {
sw.writeProcessingInstruction(target, data)
def writeCData(data: String): Unit =
- sw.writeCData(data)
+ sw.writeCData(filterXmlText(data))
def writeDTD(dtd: String): Unit =
sw.writeDTD(dtd)
@@ -291,10 +284,7 @@ final class PhobosStreamWriter(sw: XMLStreamWriter2) extends XMLStreamWriter2 {
sw.writeStartDocument(encoding, version)
def writeCharacters(text: String): Unit =
- sw.writeCharacters(text)
-
- def writeCharacters(text: Array[Char], start: Int, len: Int): Unit =
- sw.writeCharacters(text, start, len)
+ sw.writeCharacters(filterXmlText(text))
def getPrefix(uri: String): String =
sw.getPrefix(uri)
@@ -326,8 +316,16 @@ final class PhobosStreamWriter(sw: XMLStreamWriter2) extends XMLStreamWriter2 {
def setValidationProblemHandler(h: ValidationProblemHandler): ValidationProblemHandler =
sw.setValidationProblemHandler(h)
+ private def filterXmlText(string: String) =
+ if (string.forall(PhobosStreamWriter.isValidXmlCharacter)) string
+ else string.filter(PhobosStreamWriter.isValidXmlCharacter)
}
object PhobosStreamWriter {
val prefixBase = "ans"
+
+ def isValidXmlCharacter(char: Char): Boolean =
+ !(char < ' '
+ || 0xd800 <= char && char <= 0xdfff
+ || char == 0xfffe || char == 0xffff)
}
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..bc65549 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
@@ -28,7 +28,7 @@ object TextEncoder extends TextLiteralInstances {
*/
implicit val stringEncoder: TextEncoder[String] =
new TextEncoder[String] {
- def encodeAsText(a: String, sw: PhobosStreamWriter): Unit = sw.writeRaw(a)
+ def encodeAsText(a: String, sw: PhobosStreamWriter): Unit = sw.writeCharacters(a)
}
implicit val unitEncoder: TextEncoder[Unit] =
diff --git a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/XmlEncoder.scala b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/XmlEncoder.scala
index 23c74ca..400de64 100644
--- a/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/XmlEncoder.scala
+++ b/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/XmlEncoder.scala
@@ -24,10 +24,40 @@ trait XmlEncoder[A] {
val preferredNamespacePrefix: Option[String] = None
val elementEncoder: ElementEncoder[A]
- def encode(a: A, charset: String = "UTF-8"): String =
- new String(encodeToBytes(a, charset), charset)
+ // Methods below previously returned a pure value, now these methods return Either to handle encoding errors.
+ // Use -Unsafe versions for the old behavior.
+ //
+ // Encoding may fail if resulting XML document has illegal characters (https://www.w3.org/TR/xml11/#charsets)
+ // or if attribute and element names are invalid, for example "1stElement".
- def encodeToBytes(a: A, charset: String = "UTF-8"): Array[Byte] = {
+ def encode(a: A, charset: String = "UTF-8"): Either[EncodingError, String] =
+ wrapXmlException(encodeUnsafe(a, charset))
+
+ def encodeToBytes(a: A, charset: String = "UTF-8"): Either[EncodingError, Array[Byte]] =
+ wrapXmlException(encodeToBytesUnsafe(a, charset))
+
+ def encodeWithConfig(a: A, config: XmlEncoderConfig): Either[EncodingError, String] =
+ wrapXmlException(encodeWithConfigUnsafe(a, config))
+
+ def encodeToBytesWithConfig(a: A, config: XmlEncoderConfig): Either[EncodingError, Array[Byte]] =
+ wrapXmlException(encodeToBytesWithConfigUnsafe(a, config))
+
+ def encodePrettyWithConfig(a: A, config: XmlEncoderConfig, ident: Int = 2): Either[EncodingError, String] =
+ wrapXmlException(encodePrettyWithConfigUnsafe(a, config, ident))
+
+ def encodePretty(a: A, charset: String = "UTF-8", ident: Int = 2): Either[EncodingError, String] =
+ wrapXmlException(encodePrettyUnsafe(a, charset, ident))
+
+ // Methods below can throw exceptions in some rare cases. Use "safe" methods returning Either,
+ // if you are not sure about the correctness of the data being encoded.
+ //
+ // These method may throw if resulting XML document has illegal characters ([[https://www.w3.org/TR/xml11/#charsets]])
+ // or if attribute and element names are invalid, for example "1stElement".
+
+ def encodeUnsafe(a: A, charset: String = "UTF-8"): String =
+ new String(encodeToBytesUnsafe(a, charset), charset)
+
+ def encodeToBytesUnsafe(a: A, charset: String = "UTF-8"): Array[Byte] = {
val os = new ByteArrayOutputStream
val sw =
new PhobosStreamWriter(XmlEncoder.factory.createXMLStreamWriter(os, charset).asInstanceOf[XMLStreamWriter2])
@@ -39,10 +69,10 @@ trait XmlEncoder[A] {
os.toByteArray
}
- def encodeWithConfig(a: A, config: XmlEncoderConfig): String =
- new String(encodeToBytesWithConfig(a, config), config.encoding)
+ def encodeWithConfigUnsafe(a: A, config: XmlEncoderConfig): String =
+ new String(encodeToBytesWithConfigUnsafe(a, config), config.encoding)
- def encodeToBytesWithConfig(a: A, config: XmlEncoderConfig): Array[Byte] = {
+ def encodeToBytesWithConfigUnsafe(a: A, config: XmlEncoderConfig): Array[Byte] = {
val os = new ByteArrayOutputStream
val sw =
new PhobosStreamWriter(
@@ -63,13 +93,17 @@ trait XmlEncoder[A] {
/** Warning: Use .encodePrettyWithConfig only for debugging, as it is less performant. For production use
* .encodeWithConfig
*/
- def encodePrettyWithConfig(a: A, config: XmlEncoderConfig, ident: Int = 2): String =
- beautifyXml(encodeWithConfig(a, config), ident)
+ def encodePrettyWithConfigUnsafe(a: A, config: XmlEncoderConfig, ident: Int = 2): String =
+ beautifyXml(encodeWithConfigUnsafe(a, config), ident)
/** Warning: Use .encodePretty only for debugging, as it is less performant. For production use .encode
*/
- def encodePretty(a: A, charset: String = "UTF-8", ident: Int = 2): String =
- beautifyXml(encode(a, charset), ident)
+ def encodePrettyUnsafe(a: A, charset: String = "UTF-8", ident: Int = 2): String =
+ beautifyXml(encodeUnsafe(a, charset), ident)
+
+ private def wrapXmlException[B](xml: => B): Either[EncodingError, B] =
+ try { Right(xml) }
+ catch { case e: Throwable => Left(EncodingError(Option(e.getMessage).getOrElse("No message provided"), Some(e))) }
private def beautifyXml(xml: String, ident: Int): String = {
val t = XmlEncoder.transformerFactory.newTransformer()
diff --git a/modules/core/src/test/scala-2.13/ru/tinkoff/phobos/LiteralDecodingTest.scala b/modules/core/src/test/scala-2.13/ru/tinkoff/phobos/LiteralDecodingTest.scala
index cfd2847..1b9ea1a 100644
--- a/modules/core/src/test/scala-2.13/ru/tinkoff/phobos/LiteralDecodingTest.scala
+++ b/modules/core/src/test/scala-2.13/ru/tinkoff/phobos/LiteralDecodingTest.scala
@@ -41,7 +41,7 @@ class LiteralDecodingTest extends AnyWordSpec with Matchers {
""".stripMargin
val decoded = XmlDecoder[Foo].decodeFromIterable(toList(string))
decoded should
- matchPattern { case Left(DecodingError("Failed to decode literal type. Expected: Ok, actual: Error", _)) => }
+ matchPattern { case Left(DecodingError("Failed to decode literal type. Expected: Ok, actual: Error", _, _)) => }
}
"fail on attributes with incorrect value sync" in failOnAttributesWithIncorrectValue(pure)
@@ -75,7 +75,7 @@ class LiteralDecodingTest extends AnyWordSpec with Matchers {
""".stripMargin
val decoded = XmlDecoder[Foo].decodeFromIterable(toList(string))
decoded should
- matchPattern { case Left(DecodingError("Failed to decode literal type. Expected: Ok, actual: Error", _)) => }
+ matchPattern { case Left(DecodingError("Failed to decode literal type. Expected: Ok, actual: Error", _, _)) => }
}
"fail on elements with incorrect value sync" in failOnElementsWithIncorrectValue(pure)
@@ -109,7 +109,7 @@ class LiteralDecodingTest extends AnyWordSpec with Matchers {
""".stripMargin
val decoded = XmlDecoder[Foo].decodeFromIterable(toList(string))
decoded should
- matchPattern { case Left(DecodingError("Failed to decode literal type. Expected: Ok, actual: Error", _)) => }
+ matchPattern { case Left(DecodingError("Failed to decode literal type. Expected: Ok, actual: Error", _, _)) => }
}
"fail on elements with incorrect value sync" in failOnElementsWithIncorrectValue(pure)
diff --git a/modules/core/src/test/scala-2.13/ru/tinkoff/phobos/LiteralEncodingTest.scala b/modules/core/src/test/scala-2.13/ru/tinkoff/phobos/LiteralEncodingTest.scala
index 9438b18..6b30606 100644
--- a/modules/core/src/test/scala-2.13/ru/tinkoff/phobos/LiteralEncodingTest.scala
+++ b/modules/core/src/test/scala-2.13/ru/tinkoff/phobos/LiteralEncodingTest.scala
@@ -15,9 +15,9 @@ class LiteralEncodingTest extends AnyWordSpec {
val string = XmlEncoder[Foo].encode(Foo("Ok"))
assert(
string ==
- """
+ Right("""
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -28,9 +28,9 @@ class LiteralEncodingTest extends AnyWordSpec {
val string = XmlEncoder[Foo].encode(Foo("Ok"))
assert(
string ==
- """
+ Right("""
| Ok
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -41,9 +41,9 @@ class LiteralEncodingTest extends AnyWordSpec {
val string = XmlEncoder[Foo].encode(Foo("Ok"))
assert(
string ==
- """
+ Right("""
| Ok
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
}
diff --git a/modules/core/src/test/scala-3/ru/tinkoff/phobos/DerivationTest.scala b/modules/core/src/test/scala-3/ru/tinkoff/phobos/DerivationTest.scala
index 01f19e5..8d16c9c 100644
--- a/modules/core/src/test/scala-3/ru/tinkoff/phobos/DerivationTest.scala
+++ b/modules/core/src/test/scala-3/ru/tinkoff/phobos/DerivationTest.scala
@@ -27,7 +27,7 @@ class DerivationTest extends AnyWordSpec with Matchers {
""".stripMargin.minimized
val encoded = XmlEncoder[Bar].encode(bar)
- assert(encoded == string)
+ assert(encoded == Right(string))
}
}
diff --git a/modules/core/src/test/scala/ru/tinkoff/phobos/AutoDerivationTest.scala b/modules/core/src/test/scala/ru/tinkoff/phobos/AutoDerivationTest.scala
index 8e48a67..ea37043 100644
--- a/modules/core/src/test/scala/ru/tinkoff/phobos/AutoDerivationTest.scala
+++ b/modules/core/src/test/scala/ru/tinkoff/phobos/AutoDerivationTest.scala
@@ -71,7 +71,7 @@ class AutoDerivationTest extends AnyWordSpec with Matchers {
|""".stripMargin
val encoder = XmlEncoder.fromElementEncoder[Baz]("baz")
- assert(encoder.encode(baz) == bazXml.minimized)
+ assert(encoder.encode(baz) == Right(bazXml.minimized))
val decoder = XmlDecoder.fromElementDecoder[Baz]("baz")
assert(decoder.decode(bazXml) == Right(baz))
diff --git a/modules/core/src/test/scala/ru/tinkoff/phobos/DecoderDerivationTest.scala b/modules/core/src/test/scala/ru/tinkoff/phobos/DecoderDerivationTest.scala
index 9e6e879..7972a6d 100644
--- a/modules/core/src/test/scala/ru/tinkoff/phobos/DecoderDerivationTest.scala
+++ b/modules/core/src/test/scala/ru/tinkoff/phobos/DecoderDerivationTest.scala
@@ -161,20 +161,25 @@ class DecoderDerivationTest extends AnyWordSpec with Matchers {
val decodedResultInvalidFoo = XmlDecoder[Wrapper].decode(invalidXmlStringAtFoo)
val decodedResultInvalidTotal = XmlDecoder[Wrapper].decode(totallyInvalidXml)
- assert(
- decodedResultInvalidFoo == Left(
- DecodingError(
- "Unexpected end tag: expected \n at [row,col {unknown-source}]: [3,8]",
- List("foo", "foo", "Wrapper"),
- ),
- ),
- )
+ decodedResultInvalidFoo should matchPattern {
+ case Left(
+ DecodingError(
+ "Unexpected end tag: expected \n at [row,col {unknown-source}]: [3,8]",
+ List("foo", "foo", "Wrapper"),
+ _,
+ ),
+ ) =>
+ }
- assert(
- decodedResultInvalidTotal == Left(
- DecodingError("Unexpected character 'L' (code 76) in prolog\n at [row,col {unknown-source}]: [1,2]", Nil),
- ),
- )
+ decodedResultInvalidTotal should matchPattern {
+ case Left(
+ DecodingError(
+ "Unexpected character 'L' (code 76) in prolog\n at [row,col {unknown-source}]: [1,2]",
+ Nil,
+ _,
+ ),
+ ) =>
+ }
}
def decodeNilValues(toList: String => List[Array[Byte]]): Assertion = {
@@ -813,7 +818,7 @@ class DecoderDerivationTest extends AnyWordSpec with Matchers {
barDecoder.decodeFromIterable(toList(string2)) == Right(bar2) &&
barDecoder.decodeFromIterable(toList(string3)) == Right(bar3) &&
barDecoder.decodeFromIterable(toList(string4)) ==
- Left(DecodingError("Unknown type discriminator value: 'Qux'", List("foo", "bar"))),
+ Left(DecodingError("Unknown type discriminator value: 'Qux'", List("foo", "bar"), None)),
)
}
@@ -1060,7 +1065,7 @@ class DecoderDerivationTest extends AnyWordSpec with Matchers {
animalXmlDecoder.decode(catString) shouldBe Right(Cat("meow"))
animalXmlDecoder.decode(dogString) shouldBe Right(Dog(1234))
animalXmlDecoder.decode(robotString) shouldBe
- Left(DecodingError("Unknown type discriminator value: 'robot'", List("robot")))
+ Left(DecodingError("Unknown type discriminator value: 'robot'", List("robot"), None))
}
"override element name with discriminator in xml decoder if configured sync" in
@@ -1458,9 +1463,9 @@ class DecoderDerivationTest extends AnyWordSpec with Matchers {
val decoded2 = XmlDecoder[Bar].decode(string2)
assert(
- decoded1 == Left(DecodingError("Invalid local name. Expected 'bar', but found 'wrong'", List("wrong"))) &&
+ decoded1 == Left(DecodingError("Invalid local name. Expected 'bar', but found 'wrong'", List("wrong"), None)) &&
decoded2 == Left(
- DecodingError("Invalid namespace. Expected 'tinkoff.ru', but found 'tcsbank.ru'", List("bar")),
+ DecodingError("Invalid namespace. Expected 'tinkoff.ru', but found 'tcsbank.ru'", List("bar"), None),
),
)
}
diff --git a/modules/core/src/test/scala/ru/tinkoff/phobos/EncoderDerivationTest.scala b/modules/core/src/test/scala/ru/tinkoff/phobos/EncoderDerivationTest.scala
index 23386c6..572d1fa 100644
--- a/modules/core/src/test/scala/ru/tinkoff/phobos/EncoderDerivationTest.scala
+++ b/modules/core/src/test/scala/ru/tinkoff/phobos/EncoderDerivationTest.scala
@@ -27,7 +27,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = xmlEncoder.encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
@@ -38,7 +38,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -53,7 +53,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
@@ -62,7 +62,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -87,13 +87,13 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val xml = XmlEncoder[Qux].encode(qux)
assert(
xml ==
- """
+ Right("""
|
|
| constant
| text
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -108,7 +108,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val xml2 = XmlEncoder[Wrapper].encode(Wrapper(None))
assert(
xml1 ==
- """
+ Right("""
|
|
|
@@ -116,12 +116,12 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 2.0
|
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
xml2 ==
- """
+ Right("""
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -145,7 +145,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val xml2 = XmlEncoder[Foos].encode(bar2)
assert(
xml1 ==
- """
+ Right("""
|
|
|
@@ -163,12 +163,12 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 4
|
|
- """.stripMargin.minimized
+ """.stripMargin.minimized)
&& xml2 ==
- """
+ Right("""
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -181,9 +181,9 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Foo].encode(foo)
assert(
string ==
- """
+ Right("""
| Zm9vYmFy
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -198,14 +198,14 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
| 3.0
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -224,7 +224,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Foo].encode(foo)
assert(
string ==
- """
+ Right("""
|
|
|
@@ -241,7 +241,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| 0
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -254,10 +254,10 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Foo].encode(foo)
assert(
string ==
- """
+ Right("""
|
| Sending item to 1Buzz
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -270,12 +270,12 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Foo].encode(foo)
assert(
string ==
- """
+ Right("""
|
|
| Esca"'<>&pe
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -290,7 +290,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
@@ -301,7 +301,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -314,13 +314,13 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Foo].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| 1
| 3.0
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -335,14 +335,14 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
| 3.0
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -358,14 +358,14 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
| 3.0
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -381,14 +381,14 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
| 3.0
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -417,8 +417,8 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
""".stripMargin.minimized
- assert(fooOptionEncoder.encode(fooOption) == fooOptionString)
- assert(fooListEncoder.encode(fooList) == fooListString)
+ assert(fooOptionEncoder.encode(fooOption) == Right(fooOptionString))
+ assert(fooListEncoder.encode(fooList) == Right(fooListString))
}
"work for nested higher-kinded data" in {
@@ -460,8 +460,8 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
""".stripMargin.minimized
- assert(barOptionEncoder.encode(barOption) == barOptionString)
- assert(barListEncoder.encode(barList) == barListString)
+ assert(barOptionEncoder.encode(barOption) == Right(barOptionString))
+ assert(barListEncoder.encode(barList) == Right(barListString))
}
}
@@ -483,7 +483,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
string1 ==
- """
+ Right("""
|
|
| d value
@@ -492,9 +492,9 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| k
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
string2 ==
- """
+ Right("""
|
|
| d value
@@ -503,9 +503,9 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| e
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
string3 ==
- """
+ Right("""
|
|
| another one value
@@ -514,7 +514,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| v
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -535,7 +535,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
string1 ==
- """
+ Right("""
|
|
| d value
@@ -544,9 +544,9 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| k
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
string2 ==
- """
+ Right("""
|
|
| d value
@@ -555,9 +555,9 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| e
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
string3 ==
- """
+ Right("""
|
|
| another one value
@@ -566,7 +566,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| v
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
case class Quux(d: String, baz: SealedClasses.Baz, e: Char)
@@ -585,7 +585,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
string4 ==
- """
+ Right("""
|
|
| d value
@@ -594,9 +594,9 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| k
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
string5 ==
- """
+ Right("""
|
|
| d value
@@ -605,9 +605,9 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| e
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
string6 ==
- """
+ Right("""
|
|
| another one value
@@ -616,7 +616,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| v
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -628,23 +628,23 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
animalEncoder.encode(wolf) ==
- """
+ Right("""
|
|
| Igor
| 0.2
| 20
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
animalEncoder.encode(lion) ==
- """
+ Right("""
|
|
| Sergey
| 0.75
| 60.1
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -656,21 +656,21 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
insectEncoder.encode(hornet) ==
- """
+ Right("""
|
|
| Anton
| 200.123
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
insectEncoder.encode(cockroach) ==
- """
+ Right("""
|
|
| Dmitriy
| 5
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -682,21 +682,21 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
fishEncoder.encode(clownFish) ==
- """
+ Right("""
|
|
| Nemo
| 1
|
- """.stripMargin.minimized &&
+ """.stripMargin.minimized) &&
fishEncoder.encode(whiteShark) ==
- """
+ Right("""
|
|
| Bill
| 20000000000
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -723,7 +723,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
""".stripMargin.minimized
val zoo = Zoo(List(Cow(12.432), Cat("meow"), Dog(1234), Cat("nya")))
- XmlEncoder[Zoo].encode(zoo) shouldBe string
+ XmlEncoder[Zoo].encode(zoo) shouldBe Right(string)
}
"override element name with discriminator in xml encoder if configured" in {
@@ -743,8 +743,8 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 1234
|
|""".stripMargin.minimized
- animalXmlEncoder.encode(cat) shouldBe catString
- animalXmlEncoder.encode(dog) shouldBe dogString
+ animalXmlEncoder.encode(cat) shouldBe Right(catString)
+ animalXmlEncoder.encode(dog) shouldBe Right(dogString)
}
}
@@ -770,7 +770,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
@@ -781,7 +781,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -806,7 +806,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
@@ -815,7 +815,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -840,7 +840,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
@@ -849,7 +849,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -876,7 +876,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
@@ -885,7 +885,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -910,7 +910,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
@@ -920,7 +920,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -945,7 +945,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| d value
@@ -955,7 +955,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -972,13 +972,13 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
| d value
| 3.0
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -999,7 +999,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
string ==
- """
+ Right("""
|
|
| 1
@@ -1008,7 +1008,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -1031,7 +1031,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
string ==
- """
+ Right("""
|
|
| 1
@@ -1040,7 +1040,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
| e
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -1060,7 +1060,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
string ==
- """
+ Right("""
|
|
| 1
@@ -1068,7 +1068,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -1091,7 +1091,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
string ==
- """
+ Right("""
|
|
| 1
@@ -1099,7 +1099,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -1125,13 +1125,13 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
string ==
- """
+ Right("""
|
| 1
| b value
| 3.0
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -1164,7 +1164,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -1203,7 +1203,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
|
| 1
@@ -1211,7 +1211,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 3.0
|
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -1238,7 +1238,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|""".stripMargin.minimized
val aquarium =
Aquarium(List(SealedClasses.Amphiprion("Marlin", 3), SealedClasses.CarcharodonCarcharias("Jaws", 1234)))
- XmlEncoder[Aquarium].encode(aquarium) shouldBe string
+ XmlEncoder[Aquarium].encode(aquarium) shouldBe Right(string)
}
"encode sealed traits using element names as discriminators" in {
@@ -1261,7 +1261,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
""".stripMargin.minimized
val animalShelter = AnimalShelter(List(Cat("meow"), Dog(1234)))
- XmlEncoder[AnimalShelter].encode(animalShelter) shouldBe string
+ XmlEncoder[AnimalShelter].encode(animalShelter) shouldBe Right(string)
}
"encode namespaces with preferred prefixes" in {
@@ -1289,7 +1289,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
""".stripMargin.minimized
- XmlEncoder[Foo].encode(foo) shouldBe string
+ XmlEncoder[Foo].encode(foo) shouldBe Right(string)
}
"declare namespaces with preferred prefixes from config" in {
@@ -1314,13 +1314,13 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
assert(
string ==
- """
+ Right("""
|
| 1
| b value
| 3.0
|
- """.stripMargin.minimized,
+ """.stripMargin.minimized),
)
}
@@ -1350,7 +1350,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
| 123
| b value
@@ -1369,7 +1369,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
|
|
|
- |""".stripMargin.minimized,
+ |""".stripMargin.minimized),
)
}
@@ -1399,7 +1399,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
val string = XmlEncoder[Bar].encode(bar)
assert(
string ==
- """
+ Right("""
|
| 123
| b value
@@ -1410,7 +1410,7 @@ class EncoderDerivationTest extends AnyWordSpec with Matchers {
| 4.321
|
|
- |""".stripMargin.minimized,
+ |""".stripMargin.minimized),
)
}
}
diff --git a/modules/core/src/test/scala/ru/tinkoff/phobos/XmlEncoderTest.scala b/modules/core/src/test/scala/ru/tinkoff/phobos/XmlEncoderTest.scala
index 40377b1..cc913ff 100644
--- a/modules/core/src/test/scala/ru/tinkoff/phobos/XmlEncoderTest.scala
+++ b/modules/core/src/test/scala/ru/tinkoff/phobos/XmlEncoderTest.scala
@@ -12,7 +12,7 @@ class XmlEncoderTest extends AnyWordSpec with Matchers {
implicit val fooEncoder: XmlEncoder[Foo] = deriveXmlEncoder("Foo")
XmlEncoder[Foo].encodeWithConfig(Foo(1, "abc", 1.0), XmlEncoder.defaultConfig.withoutProlog) shouldBe
- "1abc1.0"
+ Right("1abc1.0")
}
"not ignore prolog by default" in {
@@ -20,7 +20,7 @@ class XmlEncoderTest extends AnyWordSpec with Matchers {
implicit val fooEncoder: XmlEncoder[Foo] = deriveXmlEncoder("Foo")
XmlEncoder[Foo].encodeWithConfig(Foo(1, "abc", 1.0), XmlEncoder.defaultConfig) shouldBe
- "1abc1.0"
+ Right("1abc1.0")
}
"overwrite prolog information if configured" in {
@@ -28,7 +28,7 @@ class XmlEncoderTest extends AnyWordSpec with Matchers {
implicit val fooEncoder: XmlEncoder[Foo] = deriveXmlEncoder("Foo")
XmlEncoder[Foo].encodeWithConfig(Foo(1, "abc", 1.0), XmlEncoder.XmlEncoderConfig("UTF-16", "1.1", true)) shouldBe
- "1abc1.0"
+ Right("1abc1.0")
}
}
}
diff --git a/modules/enumeratum/src/main/scala/ru/tinkoff/phobos/enumeratum/XmlEnum.scala b/modules/enumeratum/src/main/scala/ru/tinkoff/phobos/enumeratum/XmlEnum.scala
index 79e236f..6693689 100644
--- a/modules/enumeratum/src/main/scala/ru/tinkoff/phobos/enumeratum/XmlEnum.scala
+++ b/modules/enumeratum/src/main/scala/ru/tinkoff/phobos/enumeratum/XmlEnum.scala
@@ -11,7 +11,7 @@ trait XmlEnum[A <: EnumEntry] { this: Enum[A] =>
def decodeFromString(history: List[String], str: String): Either[DecodingError, A] = this.withNameOption(str) match {
case Some(member) => Right(member)
- case _ => Left(DecodingError(s"'$str' in not a member of enum $this", history))
+ case _ => Left(DecodingError(s"'$str' in not a member of enum $this", history, None))
}
implicit val enumElementDecoder: ElementDecoder[A] = ElementDecoder.stringDecoder.emap(decodeFromString)
diff --git a/modules/enumeratum/src/test/scala/ru/tinkoff/phobos/enumeratum/EnumeratumTest.scala b/modules/enumeratum/src/test/scala/ru/tinkoff/phobos/enumeratum/EnumeratumTest.scala
index de2ccb3..089705f 100644
--- a/modules/enumeratum/src/test/scala/ru/tinkoff/phobos/enumeratum/EnumeratumTest.scala
+++ b/modules/enumeratum/src/test/scala/ru/tinkoff/phobos/enumeratum/EnumeratumTest.scala
@@ -34,45 +34,49 @@ class EnumeratumTest extends AnyWordSpec with Matchers {
val xml2 = XmlEncoder[Bar].encode(bar2)
val xml3 = XmlEncoder[Bar].encode(bar3)
val xml4 = XmlEncoder[Baz].encode(baz)
+ val string1 =
+ """
+ |
+ |
+ | d value
+ |
+ | Foo1
+ |
+ | e
+ |
+ """.stripMargin.minimized
+ val string2 =
+ """
+ |
+ |
+ | d value
+ |
+ | Foo2
+ |
+ | e
+ |
+ """.stripMargin.minimized
+ val string3 =
+ """
+ |
+ |
+ | another one value
+ |
+ | Foo3
+ |
+ | v
+ |
+ """.stripMargin.minimized
+ val string4 =
+ """
+ |
+ | Foo2
+ """.stripMargin.minimized
assert(
- xml1 ==
- """
- |
- |
- | d value
- |
- | Foo1
- |
- | e
- |
- """.stripMargin.minimized &&
- xml2 ==
- """
- |
- |
- | d value
- |
- | Foo2
- |
- | e
- |
- """.stripMargin.minimized &&
- xml3 ==
- """
- |
- |
- | another one value
- |
- | Foo3
- |
- | v
- |
- """.stripMargin.minimized &&
- xml4 ==
- """
- |
- | Foo2
- """.stripMargin.minimized,
+ xml1 == Right(string1) &&
+ xml2 == Right(string2) &&
+ xml3 == Right(string3) &&
+ xml4 == Right(string4),
)
}
diff --git a/modules/fs2-ce2/src/test/scala/ru/tinkoff/phobos/test/ParseTest.scala b/modules/fs2-ce2/src/test/scala/ru/tinkoff/phobos/test/ParseTest.scala
index 3908252..9da5622 100644
--- a/modules/fs2-ce2/src/test/scala/ru/tinkoff/phobos/test/ParseTest.scala
+++ b/modules/fs2-ce2/src/test/scala/ru/tinkoff/phobos/test/ParseTest.scala
@@ -73,12 +73,12 @@ class ParseTest extends AsyncWordSpec with Inspectors {
xml.nestedRepetetive -> Vector(1, 2, 3, 4).map(Foo(_)).map(Right(_)),
xml.nestedRepetetiveIcnludingOtherTags -> Vector(
Right(Foo(1)),
- Left(DecodingError("Invalid local name. Expected 'foo', but found 'bar'", List("bar", "sub", "root"))),
+ Left(DecodingError("Invalid local name. Expected 'foo', but found 'bar'", List("bar", "sub", "root"), None)),
Right(Foo(2)),
Right(Foo(3)),
Right(Foo(4)),
Right(Foo(5)),
- Left(DecodingError("Invalid local name. Expected 'foo', but found 'bar'", List("bar", "sub", "root"))),
+ Left(DecodingError("Invalid local name. Expected 'foo', but found 'bar'", List("bar", "sub", "root"), None)),
),
)
diff --git a/modules/fs2/src/test/scala/ru/tinkoff/phobos/test/ParseTest.scala b/modules/fs2/src/test/scala/ru/tinkoff/phobos/test/ParseTest.scala
index 244e605..a680862 100644
--- a/modules/fs2/src/test/scala/ru/tinkoff/phobos/test/ParseTest.scala
+++ b/modules/fs2/src/test/scala/ru/tinkoff/phobos/test/ParseTest.scala
@@ -77,12 +77,12 @@ class ParseTest extends AsyncWordSpec with Inspectors {
xml.nestedRepetetive -> Vector(1, 2, 3, 4).map(Foo(_)).map(Right(_)),
xml.nestedRepetetiveIcnludingOtherTags -> Vector(
Right(Foo(1)),
- Left(DecodingError("Invalid local name. Expected 'foo', but found 'bar'", List("bar", "sub", "root"))),
+ Left(DecodingError("Invalid local name. Expected 'foo', but found 'bar'", List("bar", "sub", "root"), None)),
Right(Foo(2)),
Right(Foo(3)),
Right(Foo(4)),
Right(Foo(5)),
- Left(DecodingError("Invalid local name. Expected 'foo', but found 'bar'", List("bar", "sub", "root"))),
+ Left(DecodingError("Invalid local name. Expected 'foo', but found 'bar'", List("bar", "sub", "root"), None)),
),
)
diff --git a/modules/refined/src/main/scala/ru/tinkoff/phobos/refined/decoding/DecodingInstances.scala b/modules/refined/src/main/scala/ru/tinkoff/phobos/refined/decoding/DecodingInstances.scala
index 34af0c9..00d84b0 100644
--- a/modules/refined/src/main/scala/ru/tinkoff/phobos/refined/decoding/DecodingInstances.scala
+++ b/modules/refined/src/main/scala/ru/tinkoff/phobos/refined/decoding/DecodingInstances.scala
@@ -53,6 +53,7 @@ trait DecodingInstances {
DecodingError(
s"Failed to verify $P refinement for value=$rawValue of raw type $T: $error",
history,
+ None,
)
}
}
diff --git a/modules/refined/src/test/scala/ru/tinkoff/phobos/refined/RefinedEncodersTest.scala b/modules/refined/src/test/scala/ru/tinkoff/phobos/refined/RefinedEncodersTest.scala
index 8432afd..d2d5b95 100644
--- a/modules/refined/src/test/scala/ru/tinkoff/phobos/refined/RefinedEncodersTest.scala
+++ b/modules/refined/src/test/scala/ru/tinkoff/phobos/refined/RefinedEncodersTest.scala
@@ -30,7 +30,7 @@ class RefinedEncodersTest extends AnyWordSpec with Matchers {
|
""".stripMargin.minimized
- XmlEncoder[Test].encode(value) shouldEqual expectedResult
+ XmlEncoder[Test].encode(value) shouldEqual Right(expectedResult)
}
"encode elements correctly" in {
@@ -47,7 +47,7 @@ class RefinedEncodersTest extends AnyWordSpec with Matchers {
|
""".stripMargin.minimized
- XmlEncoder[Test].encode(value) shouldEqual expectedResult
+ XmlEncoder[Test].encode(value) shouldEqual Right(expectedResult)
}
"encode text correctly" in {
@@ -58,16 +58,15 @@ class RefinedEncodersTest extends AnyWordSpec with Matchers {
val qux = Qux("42", Foo(42, NonNegLong(1000L)))
val xml = XmlEncoder[Qux].encode(qux)
- assert(
- xml ==
- """
+ val string =
+ """
|
|
| 42
| 1000
|
- """.stripMargin.minimized,
- )
+ """.stripMargin.minimized
+ assert(xml == Right(string))
}
}
}