From 5b6fb62bb9bda8dd6b5444c3bf72d548c10d1d5e Mon Sep 17 00:00:00 2001 From: hperl <34397+hperl@users.noreply.github.com> Date: Thu, 24 Nov 2022 17:33:48 +0100 Subject: [PATCH] feat: support Array<> syntax in type decl You can now use `Array` as an alternative to `T[]` when declaring types for relations in the Ory Permission Language. --- internal/schema/parser.go | 34 +++++++++++++++++++++------------- internal/schema/parser_test.go | 6 +++--- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/internal/schema/parser.go b/internal/schema/parser.go index 0ea022644..06c2f28b9 100644 --- a/internal/schema/parser.go +++ b/internal/schema/parser.go @@ -193,28 +193,36 @@ func (p *parser) parseRelated() { p.match(":", "{") for !p.fatal { switch item := p.next(); item.Typ { + case itemBraceRight: return + case itemIdentifier, itemStringLiteral: relation := item.Val var types []ast.RelationType p.match(":") - switch item := p.next(); item.Typ { - case itemIdentifier: - if item.Val == "SubjectSet" { - types = append(types, p.matchSubjectSet()) - } else { - types = append(types, ast.RelationType{Namespace: item.Val}) - p.addCheck(checkNamespaceExists(item)) - } - case itemParenLeft: - types = append(types, p.parseTypeUnion()...) + + switch item := p.next(); { + case item.Val == "Array": + p.match("<") + types = append(types, p.parseTypeUnion(itemAngledRight)...) + case item.Val == "SubjectSet": + types = append(types, p.matchSubjectSet()) + p.match("[", "]", optional(",")) + case item.Typ == itemParenLeft: + types = append(types, p.parseTypeUnion(itemParenRight)...) + p.match("[", "]", optional(",")) + default: + types = append(types, ast.RelationType{Namespace: item.Val}) + p.addCheck(checkNamespaceExists(item)) + p.match("[", "]", optional(",")) } - p.match("[", "]", optional(",")) + p.namespace.Relations = append(p.namespace.Relations, ast.Relation{ Name: relation, Types: types, }) + default: p.addFatal(item, "expected identifier or '}', got %s %q", item.Typ.String(), item.Val) return @@ -229,7 +237,7 @@ func (p *parser) matchSubjectSet() ast.RelationType { return ast.RelationType{Namespace: namespace.Val, Relation: relation.Val} } -func (p *parser) parseTypeUnion() (types []ast.RelationType) { +func (p *parser) parseTypeUnion(endToken itemType) (types []ast.RelationType) { for !p.fatal { var identifier item p.match(&identifier) @@ -240,7 +248,7 @@ func (p *parser) parseTypeUnion() (types []ast.RelationType) { p.addCheck(checkNamespaceExists(identifier)) } switch item := p.next(); item.Typ { - case itemParenRight: + case endToken: return case itemTypeUnion: default: diff --git a/internal/schema/parser_test.go b/internal/schema/parser_test.go index c00d94527..33a5ee61b 100644 --- a/internal/schema/parser_test.go +++ b/internal/schema/parser_test.go @@ -77,8 +77,8 @@ var parserTestCases = []struct { class Folder implements Namespace { related: { - parents: File[] - viewers: SubjectSet[] + parents: Array + viewers: Array> } permits = { @@ -88,7 +88,7 @@ var parserTestCases = []struct { class File implements Namespace { related: { - parents: (File | Folder)[] + parents: Array viewers: (User | SubjectSet)[] "owners": (User | SubjectSet)[] siblings: File[]