diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d08f3d..0e3af45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Added ## Changed +- Tuple type now attempts to calculate the number of "expected" values in a way that respects optional or defaultable schema. (#34) # [v0.2.1](https://github.com/typst-community/valakyrie/releases/tags/v0.2.1) diff --git a/src/types/tuple.typ b/src/types/tuple.typ index 151c3f7..3b0cf56 100644 --- a/src/types/tuple.typ +++ b/src/types/tuple.typ @@ -22,20 +22,48 @@ tuple-exact: exact, tuple-schema: args.pos(), handle-descendents: (self, it, ctx: z-ctx(), scope: ()) => { - if (self.tuple-exact and self.tuple-schema.len() != it.len()){ + + // Issue 34: Handle differing numbers of optional elements + + // Calculate number of expected arguments + let min-args = self.tuple-schema.filter( + x=>{ + // I'm thinking this might cause issues with table and auto? + // But can't think of a pleasant solution + x.optional==false and x.default==none + } + ).len() + let max-args = self.tuple-schema.len() + let num-args = it.len() + + // Panic if the number of arguments does not match expected + if (self.tuple-exact and (num-args > max-args or num-args < min-args)){ (self.fail-validation)(self, it, ctx: ctx, scope: scope, - message: "Expected " + str(self.tuple-schema.len()) + " values, but got " + str(it.len()) + message: "Expected " + + + if (min-args == max-args){ + str(max-args) + } else { + str(min-args) + "-" + str(max-args) + } + + + " values, but got " + + str(it.len() + ) ) } + + let parsed = () + for (key, schema) in self.tuple-schema.enumerate() { - it.at(key) = (schema.validate)( + parsed.insert(key, (schema.validate)( schema, - it.at(key), + it.at(key, default: none), ctx: ctx, scope: (..scope, str(key)), - ) + )) } - it + return parsed }, ) } diff --git a/tests/issues/34-tuples-do-not-respect-optional/ref/1.png b/tests/issues/34-tuples-do-not-respect-optional/ref/1.png new file mode 100644 index 0000000..bf69912 Binary files /dev/null and b/tests/issues/34-tuples-do-not-respect-optional/ref/1.png differ diff --git a/tests/issues/34-tuples-do-not-respect-optional/test.typ b/tests/issues/34-tuples-do-not-respect-optional/test.typ new file mode 100644 index 0000000..20516a1 --- /dev/null +++ b/tests/issues/34-tuples-do-not-respect-optional/test.typ @@ -0,0 +1,8 @@ +#import "/src/lib.typ" as z +#import "/tests/utility.typ": * + +#show: show-rule.with(); + +#let schema = z.tuple(z.string(), z.string(), z.content(optional: true)) + +#z.parse(("first", "second"), schema) \ No newline at end of file