package langV2 import ( participle "github.com/alecthomas/participle/v2" ) // Root AST node containing all definitions type AST struct { Definitions []Definition `parser:"@@*"` } type Definition struct { Entity *EntityDef `parser:"@@"` Server *ServerDef `parser:"| @@"` Page *PageDef `parser:"| @@"` Component *ComponentDef `parser:"| @@"` } type EntityDef struct { Name string `parser:"'entity' @Ident"` Fields []Field `parser:"'{' @@* '}'"` } type Field struct { Name string `parser:"@Ident ':'"` Type string `parser:"@Ident"` Required bool `parser:"@'required'?"` Unique bool `parser:"@'unique'?"` Index bool `parser:"@'indexed'?"` Default *string `parser:"('default' @String)?"` Validations []Validation `parser:"@@*"` Relationship *Relationship `parser:"@@?"` } type Validation struct { Type string `parser:"'validate' @Ident"` Value *string `parser:"@String?"` } type Relationship struct { Type string `parser:"'relates' 'to' @Ident"` Cardinality string `parser:"'as' @('one' | 'many')"` ForeignKey *string `parser:"('via' @String)?"` } type ServerDef struct { Name string `parser:"'server' @Ident"` Endpoints []EndpointDef `parser:"'{' @@* '}'"` } type EndpointDef struct { Method string `parser:"@('GET'|'POST'|'PUT'|'DELETE')"` Path string `parser:"@String"` EntityRef string `parser:"'entity' @Ident"` } type ComponentDef struct { EntityRef string `parser:"@Ident"` ServerRef string `parser:"('from' @Ident)?"` } type PageDef struct { Name string `parser:"'page' @Ident"` Components []ComponentDef `parser:"'{' @@* '}'"` } func ParseInput(input string) (AST, error) { parser, err := participle.Build[AST]( participle.Unquote("String"), ) if err != nil { return AST{}, err } ast, err := parser.ParseString("", input) if err != nil { return AST{}, err } return *ast, nil }