add bracket syntax replace tests
This commit is contained in:
241
lang/lang.go
241
lang/lang.go
@ -20,7 +20,7 @@ type Definition struct {
|
||||
// Clean server syntax
|
||||
type Server struct {
|
||||
Name string `parser:"'server' @Ident"`
|
||||
Settings []ServerSetting `parser:"@@*"`
|
||||
Settings []ServerSetting `parser:"('{' @@* '}')?"` // Block-delimited settings for consistency
|
||||
}
|
||||
|
||||
type ServerSetting struct {
|
||||
@ -32,7 +32,7 @@ type ServerSetting struct {
|
||||
type Entity struct {
|
||||
Name string `parser:"'entity' @Ident"`
|
||||
Description *string `parser:"('desc' @String)?"`
|
||||
Fields []Field `parser:"@@*"`
|
||||
Fields []Field `parser:"('{' @@* '}')?"` // Block-delimited fields for consistency
|
||||
}
|
||||
|
||||
// Much cleaner field syntax
|
||||
@ -68,9 +68,9 @@ type Endpoint struct {
|
||||
Entity *string `parser:"('for' @Ident)?"`
|
||||
Description *string `parser:"('desc' @String)?"`
|
||||
Auth bool `parser:"@'auth'?"`
|
||||
Params []EndpointParam `parser:"@@*"`
|
||||
Params []EndpointParam `parser:"('{' @@*"` // Block-delimited parameters
|
||||
Response *ResponseSpec `parser:"@@?"`
|
||||
CustomLogic *string `parser:"('custom' @String)?"`
|
||||
CustomLogic *string `parser:"('custom' @String)? '}')?"` // Close block after all content
|
||||
}
|
||||
|
||||
// Clean parameter syntax
|
||||
@ -88,20 +88,17 @@ type ResponseSpec struct {
|
||||
Fields []string `parser:"('fields' '[' @Ident (',' @Ident)* ']')?"`
|
||||
}
|
||||
|
||||
// Enhanced Page definitions with layout containers and composition
|
||||
// Enhanced Page definitions with unified section model
|
||||
type Page struct {
|
||||
Name string `parser:"'page' @Ident"`
|
||||
Path string `parser:"'at' @String"`
|
||||
Layout string `parser:"'layout' @Ident"`
|
||||
Title *string `parser:"('title' @String)?"`
|
||||
Description *string `parser:"('desc' @String)?"`
|
||||
Auth bool `parser:"@'auth'?"`
|
||||
LayoutType *string `parser:"('layout' @String)?"`
|
||||
Meta []MetaTag `parser:"@@*"`
|
||||
MasterDetail *MasterDetail `parser:"@@?"`
|
||||
Containers []Container `parser:"@@*"`
|
||||
Components []Component `parser:"@@*"`
|
||||
Modals []Modal `parser:"@@*"`
|
||||
Name string `parser:"'page' @Ident"`
|
||||
Path string `parser:"'at' @String"`
|
||||
Layout string `parser:"'layout' @Ident"`
|
||||
Title *string `parser:"('title' @String)?"`
|
||||
Description *string `parser:"('desc' @String)?"`
|
||||
Auth bool `parser:"@'auth'?"`
|
||||
Meta []MetaTag `parser:"('{' @@*"` // Block-delimited content
|
||||
Sections []Section `parser:"@@*"` // Unified sections replace containers/tabs/panels/modals
|
||||
Components []Component `parser:"@@* '}')?"` // Direct components within the block
|
||||
}
|
||||
|
||||
// Meta tags for SEO
|
||||
@ -110,85 +107,68 @@ type MetaTag struct {
|
||||
Content string `parser:"@String"`
|
||||
}
|
||||
|
||||
// Container types for layout organization
|
||||
type Container struct {
|
||||
Type string `parser:"'container' @Ident"`
|
||||
Class *string `parser:"('class' @String)?"`
|
||||
Sections []Section `parser:"@@*"`
|
||||
Tabs []Tab `parser:"@@*"`
|
||||
Components []Component `parser:"@@*"`
|
||||
}
|
||||
|
||||
// Sections within containers
|
||||
// Unified Section type that replaces Container, Tab, Panel, Modal, MasterDetail
|
||||
type Section struct {
|
||||
Name string `parser:"'section' @Ident"`
|
||||
Class *string `parser:"('class' @String)?"`
|
||||
Components []Component `parser:"@@*"`
|
||||
Panels []Panel `parser:"@@*"`
|
||||
Name string `parser:"'section' @Ident"`
|
||||
Type *string `parser:"('type' @('container' | 'tab' | 'panel' | 'modal' | 'master' | 'detail'))?"`
|
||||
Class *string `parser:"('class' @String)?"`
|
||||
Label *string `parser:"('label' @String)?"` // for tabs
|
||||
Active bool `parser:"@'active'?"` // for tabs
|
||||
Trigger *string `parser:"('trigger' @String)?"` // for panels/modals/detail
|
||||
Position *string `parser:"('position' @String)?"` // for panels
|
||||
Entity *string `parser:"('for' @Ident)?"` // for panels
|
||||
Elements []SectionElement `parser:"('{' @@* '}')?"` // Block-delimited elements for unambiguous nesting
|
||||
}
|
||||
|
||||
// Tab definitions for tabbed interfaces
|
||||
type Tab struct {
|
||||
Name string `parser:"'tab' @Ident"`
|
||||
Label string `parser:"'label' @String"`
|
||||
Active bool `parser:"@'active'?"`
|
||||
Components []Component `parser:"@@*"`
|
||||
// New unified element type for sections
|
||||
type SectionElement struct {
|
||||
Attribute *SectionAttribute `parser:"@@"`
|
||||
Component *Component `parser:"| @@"`
|
||||
Section *Section `parser:"| @@"`
|
||||
When *WhenCondition `parser:"| @@"`
|
||||
}
|
||||
|
||||
// Panel definitions for slide-out or overlay interfaces
|
||||
type Panel struct {
|
||||
Name string `parser:"'panel' @Ident"`
|
||||
Entity *string `parser:"('for' @Ident)?"`
|
||||
Trigger string `parser:"'trigger' @String"`
|
||||
Position *string `parser:"('position' @String)?"`
|
||||
Components []Component `parser:"@@*"`
|
||||
// Flexible section attributes (replaces complex config types)
|
||||
type SectionAttribute struct {
|
||||
DataSource *string `parser:"('data' 'from' @String)"`
|
||||
Style *string `parser:"| ('style' @String)"`
|
||||
Classes *string `parser:"| ('classes' @String)"`
|
||||
Size *int `parser:"| ('size' @Int)"` // for pagination, etc.
|
||||
Theme *string `parser:"| ('theme' @String)"`
|
||||
}
|
||||
|
||||
// Modal definitions
|
||||
type Modal struct {
|
||||
Name string `parser:"'modal' @Ident"`
|
||||
Trigger string `parser:"'trigger' @String"`
|
||||
Components []Component `parser:"@@*"`
|
||||
}
|
||||
|
||||
// Master-detail layout components - simplified parsing
|
||||
type MasterDetail struct {
|
||||
Master *MasterSection `parser:"'master' @@"`
|
||||
Detail *DetailSection `parser:"'detail' @@"`
|
||||
}
|
||||
|
||||
type MasterSection struct {
|
||||
Name string `parser:"@Ident"`
|
||||
Components []Component `parser:"@@*"`
|
||||
}
|
||||
|
||||
type DetailSection struct {
|
||||
Name string `parser:"@Ident"`
|
||||
Trigger *string `parser:"('trigger' @String)?"`
|
||||
Components []Component `parser:"@@*"`
|
||||
}
|
||||
|
||||
// Enhanced Component definitions with detailed field configurations
|
||||
// Simplified Component with unified attributes - reordered for better parsing
|
||||
type Component struct {
|
||||
Type string `parser:"'component' @Ident"`
|
||||
Entity *string `parser:"('for' @Ident)?"`
|
||||
Elements []ComponentElement `parser:"@@*"`
|
||||
Elements []ComponentElement `parser:"('{' @@* '}')?"` // Parse everything inside the block
|
||||
}
|
||||
|
||||
// Union type for component elements to allow flexible ordering
|
||||
// Enhanced ComponentElement with recursive section support - now includes attributes
|
||||
type ComponentElement struct {
|
||||
Config *ComponentAttr `parser:"@@"`
|
||||
Field *ComponentField `parser:"| @@"`
|
||||
Condition *WhenCondition `parser:"| @@"`
|
||||
Section *ComponentSection `parser:"| @@"`
|
||||
Action *ComponentButtonAttr `parser:"| @@"`
|
||||
Attribute *ComponentAttr `parser:"@@"` // Component attributes can be inside the block
|
||||
Field *ComponentField `parser:"| @@"`
|
||||
Section *Section `parser:"| @@"` // Sections can be nested in components
|
||||
Button *ComponentButton `parser:"| @@"`
|
||||
When *WhenCondition `parser:"| @@"`
|
||||
}
|
||||
|
||||
// Simplified component attributes using key-value pattern - reordered for precedence
|
||||
type ComponentAttr struct {
|
||||
DataSource *string `parser:"('data' 'from' @String)"`
|
||||
Fields []string `parser:"| ('fields' '[' @Ident (',' @Ident)* ']')"`
|
||||
Actions []string `parser:"| ('actions' '[' @Ident (',' @Ident)* ']')"`
|
||||
Style *string `parser:"| ('style' @String)"`
|
||||
Classes *string `parser:"| ('classes' @String)"`
|
||||
PageSize *int `parser:"| ('pagination' 'size' @Int)"`
|
||||
Validate bool `parser:"| @'validate'"`
|
||||
}
|
||||
|
||||
// Enhanced component field with detailed configuration using flexible attributes
|
||||
type ComponentField struct {
|
||||
Name string `parser:"'field' @Ident"`
|
||||
Type string `parser:"'type' @Ident"`
|
||||
Attributes []ComponentFieldAttribute `parser:"@@*"`
|
||||
Attributes []ComponentFieldAttribute `parser:"@@* ('{' @@* '}')?"` // Support both inline and block attributes
|
||||
}
|
||||
|
||||
// Flexible field attribute system
|
||||
@ -223,96 +203,67 @@ type ComponentValidation struct {
|
||||
Value *string `parser:"@String?"`
|
||||
}
|
||||
|
||||
// Conditional rendering
|
||||
// Enhanced WhenCondition with recursive support for both sections and components
|
||||
type WhenCondition struct {
|
||||
Field string `parser:"'when' @Ident"`
|
||||
Operator string `parser:"@('equals' | 'not_equals' | 'contains')"`
|
||||
Value string `parser:"@String"`
|
||||
Fields []ComponentField `parser:"@@*"`
|
||||
Sections []ComponentSection `parser:"@@*"`
|
||||
Buttons []ComponentButtonAttr `parser:"@@*"`
|
||||
Field string `parser:"'when' @Ident"`
|
||||
Operator string `parser:"@('equals' | 'not_equals' | 'contains')"`
|
||||
Value string `parser:"@String"`
|
||||
Fields []ComponentField `parser:"('{' @@*"`
|
||||
Sections []Section `parser:"@@*"` // Can contain sections
|
||||
Components []Component `parser:"@@*"` // Can contain components
|
||||
Buttons []ComponentButton `parser:"@@* '}')?"` // Block-delimited for unambiguous nesting
|
||||
}
|
||||
|
||||
// Component sections for grouping
|
||||
type ComponentSection struct {
|
||||
Name string `parser:"'section' @Ident"`
|
||||
Class *string `parser:"('class' @String)?"`
|
||||
Fields []ComponentField `parser:"@@*"`
|
||||
Buttons []ComponentButtonAttr `parser:"@@*"`
|
||||
Actions []ComponentButtonAttr `parser:"@@*"`
|
||||
// Simplified button with flexible attribute ordering
|
||||
type ComponentButton struct {
|
||||
Name string `parser:"'button' @Ident"`
|
||||
Label string `parser:"'label' @String"`
|
||||
Attributes []ComponentButtonAttr `parser:"@@*"`
|
||||
}
|
||||
|
||||
// Enhanced component buttons/actions with detailed configuration
|
||||
// Flexible button attribute system - each attribute is a separate alternative
|
||||
type ComponentButtonAttr struct {
|
||||
Name string `parser:"'button' @Ident"`
|
||||
Label string `parser:"'label' @String"`
|
||||
Style *string `parser:"('style' @String)?"`
|
||||
Icon *string `parser:"('icon' @String)?"`
|
||||
Loading *string `parser:"('loading' @String)?"`
|
||||
Disabled *string `parser:"('disabled' 'when' @Ident)?"`
|
||||
Confirm *string `parser:"('confirm' @String)?"`
|
||||
Target *string `parser:"('target' @Ident)?"`
|
||||
Position *string `parser:"('position' @String)?"`
|
||||
Via *string `parser:"('via' @String)?"`
|
||||
Style *ComponentButtonStyle `parser:"@@"`
|
||||
Icon *ComponentButtonIcon `parser:"| @@"`
|
||||
Loading *ComponentButtonLoading `parser:"| @@"`
|
||||
Disabled *ComponentButtonDisabled `parser:"| @@"`
|
||||
Confirm *ComponentButtonConfirm `parser:"| @@"`
|
||||
Target *ComponentButtonTarget `parser:"| @@"`
|
||||
Position *ComponentButtonPosition `parser:"| @@"`
|
||||
Via *ComponentButtonVia `parser:"| @@"`
|
||||
}
|
||||
|
||||
// Component attributes and configurations (keeping existing for backward compatibility)
|
||||
type ComponentAttr struct {
|
||||
Fields *ComponentFields `parser:"@@"`
|
||||
Actions *ComponentActions `parser:"| @@"`
|
||||
DataSource *ComponentDataSource `parser:"| @@"`
|
||||
Style *ComponentStyle `parser:"| @@"`
|
||||
Pagination *ComponentPagination `parser:"| @@"`
|
||||
Filters *ComponentFilters `parser:"| @@"`
|
||||
Validation bool `parser:"| @'validate'"`
|
||||
// Individual button attribute types
|
||||
type ComponentButtonStyle struct {
|
||||
Value string `parser:"'style' @String"`
|
||||
}
|
||||
|
||||
// Component field specification (simple version for backward compatibility)
|
||||
type ComponentFields struct {
|
||||
Fields []string `parser:"'fields' '[' @Ident (',' @Ident)* ']'"`
|
||||
type ComponentButtonIcon struct {
|
||||
Value string `parser:"'icon' @String"`
|
||||
}
|
||||
|
||||
// Enhanced component actions
|
||||
type ComponentActions struct {
|
||||
Actions []ComponentAction `parser:"'actions' '[' @@ (',' @@)* ']'"`
|
||||
type ComponentButtonLoading struct {
|
||||
Value string `parser:"'loading' @String"`
|
||||
}
|
||||
|
||||
type ComponentAction struct {
|
||||
Name string `parser:"@Ident"`
|
||||
Label *string `parser:"('label' @String)?"`
|
||||
Icon *string `parser:"('icon' @String)?"`
|
||||
Style *string `parser:"('style' @String)?"`
|
||||
Endpoint *string `parser:"('via' @String)?"`
|
||||
Target *string `parser:"('target' @Ident)?"`
|
||||
Position *string `parser:"('position' @String)?"`
|
||||
Confirm *string `parser:"('confirm' @String)?"`
|
||||
type ComponentButtonDisabled struct {
|
||||
Value string `parser:"'disabled' 'when' @Ident"`
|
||||
}
|
||||
|
||||
// Data source configuration (can reference endpoints)
|
||||
type ComponentDataSource struct {
|
||||
Endpoint string `parser:"'data' 'from' @String"`
|
||||
type ComponentButtonConfirm struct {
|
||||
Value string `parser:"'confirm' @String"`
|
||||
}
|
||||
|
||||
// Component styling
|
||||
type ComponentStyle struct {
|
||||
Theme *string `parser:"'style' @Ident"`
|
||||
Classes []string `parser:"('classes' '[' @String (',' @String)* ']')?"`
|
||||
type ComponentButtonTarget struct {
|
||||
Value string `parser:"'target' @Ident"`
|
||||
}
|
||||
|
||||
// Pagination configuration
|
||||
type ComponentPagination struct {
|
||||
PageSize *int `parser:"'pagination' ('size' @Int)?"`
|
||||
type ComponentButtonPosition struct {
|
||||
Value string `parser:"'position' @String"`
|
||||
}
|
||||
|
||||
// Filter specifications
|
||||
type ComponentFilters struct {
|
||||
Filters []ComponentFilter `parser:"'filters' '[' @@ (',' @@)* ']'"`
|
||||
}
|
||||
|
||||
type ComponentFilter struct {
|
||||
Field string `parser:"@Ident"`
|
||||
Type string `parser:"'as' @('text' | 'select' | 'date' | 'number')"`
|
||||
Label *string `parser:"('label' @String)?"`
|
||||
type ComponentButtonVia struct {
|
||||
Value string `parser:"'via' @String"`
|
||||
}
|
||||
|
||||
func ParseInput(input string) (AST, error) {
|
||||
|
Reference in New Issue
Block a user