Skip to content

Commit 13fa836

Browse files
authored
Merge pull request #29 from filosganga/collect-alternatives-errors
Collect-alternatives-errors
2 parents 8f936a0 + cf5f8b5 commit 13fa836

File tree

5 files changed

+85
-59
lines changed

5 files changed

+85
-59
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
strategy:
2727
matrix:
2828
os: [ubuntu-latest]
29-
scala: [2.13.6, 3.2.0, 2.12.14]
29+
scala: [2.13.10, 3.2.2, 2.12.14]
3030
java: [temurin@11]
3131
runs-on: ${{ matrix.os }}
3232
steps:
@@ -59,7 +59,7 @@ jobs:
5959

6060
- run: sbt ++${{ matrix.scala }} ci
6161

62-
- if: matrix.scala == '2.13.6'
62+
- if: matrix.scala == '2.13.10'
6363
run: sbt ++${{ matrix.scala }} docs/mdoc
6464

6565
- name: Compress target directories
@@ -78,7 +78,7 @@ jobs:
7878
strategy:
7979
matrix:
8080
os: [ubuntu-latest]
81-
scala: [2.13.6]
81+
scala: [2.13.10]
8282
java: [temurin@11]
8383
runs-on: ${{ matrix.os }}
8484
steps:
@@ -106,22 +106,22 @@ jobs:
106106
~/Library/Caches/Coursier/v1
107107
key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
108108

109-
- name: Download target directories (2.13.6)
109+
- name: Download target directories (2.13.10)
110110
uses: actions/download-artifact@v2
111111
with:
112-
name: target-${{ matrix.os }}-2.13.6-${{ matrix.java }}
112+
name: target-${{ matrix.os }}-2.13.10-${{ matrix.java }}
113113

114-
- name: Inflate target directories (2.13.6)
114+
- name: Inflate target directories (2.13.10)
115115
run: |
116116
tar xf targets.tar
117117
rm targets.tar
118118
119-
- name: Download target directories (3.2.0)
119+
- name: Download target directories (3.2.2)
120120
uses: actions/download-artifact@v2
121121
with:
122-
name: target-${{ matrix.os }}-3.2.0-${{ matrix.java }}
122+
name: target-${{ matrix.os }}-3.2.2-${{ matrix.java }}
123123

124-
- name: Inflate target directories (3.2.0)
124+
- name: Inflate target directories (3.2.2)
125125
run: |
126126
tar xf targets.tar
127127
rm targets.tar
@@ -148,26 +148,26 @@ jobs:
148148
strategy:
149149
matrix:
150150
os: [ubuntu-latest]
151-
scala: [2.13.6]
151+
scala: [2.13.10]
152152
java: [temurin@11]
153153
runs-on: ${{ matrix.os }}
154154
steps:
155-
- name: Download target directories (2.13.6)
155+
- name: Download target directories (2.13.10)
156156
uses: actions/download-artifact@v2
157157
with:
158-
name: target-${{ matrix.os }}-2.13.6-${{ matrix.java }}
158+
name: target-${{ matrix.os }}-2.13.10-${{ matrix.java }}
159159

160-
- name: Inflate target directories (2.13.6)
160+
- name: Inflate target directories (2.13.10)
161161
run: |
162162
tar xf targets.tar
163163
rm targets.tar
164164
165-
- name: Download target directories (3.2.0)
165+
- name: Download target directories (3.2.2)
166166
uses: actions/download-artifact@v2
167167
with:
168-
name: target-${{ matrix.os }}-3.2.0-${{ matrix.java }}
168+
name: target-${{ matrix.os }}-3.2.2-${{ matrix.java }}
169169

170-
- name: Inflate target directories (3.2.0)
170+
- name: Inflate target directories (3.2.2)
171171
run: |
172172
tar xf targets.tar
173173
rm targets.tar

build.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ ThisBuild / scmInfo := Some(
1414
ThisBuild / startYear := Some(2020)
1515
Global / excludeLintKeys += scmInfo
1616

17-
val Scala213 = "2.13.6"
17+
val Scala213 = "2.13.10"
1818
ThisBuild / spiewakMainBranches := Seq("main")
1919

20-
ThisBuild / crossScalaVersions := Seq(Scala213, "3.2.0", "2.12.14")
20+
ThisBuild / crossScalaVersions := Seq(Scala213, "3.2.2", "2.12.14")
2121
ThisBuild / versionIntroduced := Map("3.0.0" -> "0.3.0")
2222
ThisBuild / scalaVersion := (ThisBuild / crossScalaVersions).value.head
2323
ThisBuild / initialCommands := """

modules/core/shared/src/main/scala/internal/decoding.scala

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package dynosaur
1818
package internal
1919

20-
import cats.{~>, Monoid, MonoidK}
20+
import cats.{~>, Monoid}
2121
import cats.syntax.all._
2222
import alleycats.std.map._
2323
import cats.free.FreeApplicative
@@ -147,16 +147,29 @@ object decoding {
147147

148148
def decodeSum[A](cases: Chain[Alt[A]]): DynamoValue => Res[A] = {
149149

150-
implicit def orElse[T]: Monoid[Option[T]] =
151-
MonoidK[Option].algebra
150+
implicit def orElsev[T]: Monoid[Either[List[Schema.ReadError], T]] =
151+
Monoid.instance(
152+
Left(List.empty),
153+
{
154+
case (Left(l), Left(r)) => Left(l ++ r)
155+
case (Left(_), r @ Right(_)) => r
156+
case (l @ Right(_), Left(_)) => l
157+
case (l @ Right(_), Right(_)) => l
158+
}
159+
)
152160

153161
cases
154162
.foldMap { alt => (v: DynamoValue) =>
155-
alt.caseSchema.read(v).map(alt.prism.inject).toOption
163+
alt.caseSchema.read(v).map(alt.prism.inject).leftMap(e => List(e))
164+
}
165+
.andThen { res =>
166+
res.leftMap { errors =>
167+
val errorsDetails = errors.map(_.message).mkString("[", ",", "]")
168+
ReadError(
169+
s"value doesn't match any of the alternatives: $errorsDetails"
170+
)
171+
}
156172
}
157-
.andThen(
158-
_.toRight(ReadError("value doesn't match any of the alternatives"))
159-
)
160173
}
161174

162175
def decodeIsos[V](xmap: XMap[V], v: DynamoValue): Res[V] =

modules/core/shared/src/test/scala/SchemaSuite.scala

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,39 @@ class SchemaSuite extends ScalaCheckSuite {
9999
assertEquals(roundTrip, data.some)
100100
}
101101

102+
val statusSchema: Schema[Status] = Schema.oneOf { alt =>
103+
val error = Schema
104+
.record[Error] { field =>
105+
field.const("type", "error") *> (
106+
field("msg", _.msg),
107+
field("cause", _.cause)
108+
).mapN(Error.apply)
109+
}
110+
111+
val warning = Schema
112+
.record[Warning] { field =>
113+
field.const("type", "warning") *> (
114+
field("msg", _.msg),
115+
field("cause", _.cause)
116+
).mapN(Warning.apply)
117+
}
118+
119+
val unknown =
120+
Schema.record[Unknown.type](
121+
_.const("type", "unknown").as(Unknown)
122+
)
123+
124+
val successful = Schema
125+
.record[Successful] { field =>
126+
field.const("type", "successful") *> (
127+
field("link", _.link),
128+
field("expires", _.expires)
129+
).mapN(Successful.apply)
130+
}
131+
132+
alt(error) |+| alt(warning) |+| alt(unknown) |+| alt(successful)
133+
}
134+
102135
test("id") {
103136
forAllNoShrink { (dv: V) =>
104137
val expected = dv
@@ -756,43 +789,11 @@ class SchemaSuite extends ScalaCheckSuite {
756789

757790
test("ADTs, via a discriminator field") {
758791
val schema: Schema[Upload] = {
759-
val error = Schema
760-
.record[Error] { field =>
761-
field.const("type", "error") *> (
762-
field("msg", _.msg),
763-
field("cause", _.cause)
764-
).mapN(Error.apply)
765-
}
766-
767-
val warning = Schema
768-
.record[Warning] { field =>
769-
field.const("type", "warning") *> (
770-
field("msg", _.msg),
771-
field("cause", _.cause)
772-
).mapN(Warning.apply)
773-
}
774-
775-
val unknown =
776-
Schema.record[Unknown.type](
777-
_.const("type", "unknown").as(Unknown)
778-
)
779-
780-
val successful = Schema
781-
.record[Successful] { field =>
782-
field.const("type", "successful") *> (
783-
field("link", _.link),
784-
field("expires", _.expires)
785-
).mapN(Successful.apply)
786-
}
787792

788793
Schema.record[Upload] { field =>
789794
(
790795
field("id", _.id),
791-
field("status", _.status) {
792-
Schema.oneOf { alt =>
793-
alt(error) |+| alt(warning) |+| alt(unknown) |+| alt(successful)
794-
}
795-
}
796+
field("status", _.status)(statusSchema)
796797
).mapN(Upload.apply)
797798
}
798799
}
@@ -962,6 +963,18 @@ class SchemaSuite extends ScalaCheckSuite {
962963
check(schema, text, expected)
963964
}
964965

966+
test("ADTs, aggregated errors") {
967+
val errorMessage = statusSchema.read(DynamoValue.n(5)).leftMap(_.message)
968+
assert(
969+
errorMessage.swap.exists(msg =>
970+
// Don't want to test the full message, I just care that there is the list of failures
971+
msg.contains("alternatives: [") && msg
972+
.contains("]")
973+
),
974+
errorMessage
975+
)
976+
}
977+
965978
val compileTimeInferenceSpec = {
966979
val userSchema: Schema[User] = Schema.record { field =>
967980
(

project/build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.7.2
1+
sbt.version=1.8.2

0 commit comments

Comments
 (0)