diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 342c640..519f76a 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -52,6 +52,6 @@ sublime_fuzzy = "0.7" similar = { version = "2", features = ["inline"] } [dev-dependencies] -insta = "1.45" +insta = "1.45.1" tempfile = "3.23.0" diff --git a/src-tauri/src/asciiscript/ast.rs b/src-tauri/src/asciiscript/ast.rs new file mode 100644 index 0000000..4b20d01 --- /dev/null +++ b/src-tauri/src/asciiscript/ast.rs @@ -0,0 +1,297 @@ +//! AST types for asciiscript DSL. +//! +//! The AST closely mirrors the grammar defined in docs/asciiscript-spec.md. + +use std::fmt; + +/// A complete asciiscript program. +#[derive(Debug, Clone, PartialEq)] +pub struct Program { + pub layout: Layout, +} + +/// The root layout container. +#[derive(Debug, Clone, PartialEq)] +pub struct Layout { + pub statements: Vec, + pub span: Span, +} + +/// A statement in a block - either a container or primitive. +#[derive(Debug, Clone, PartialEq)] +pub enum Statement { + Container(Container), + Primitive(Primitive), +} + +/// Container types that hold other statements. +#[derive(Debug, Clone, PartialEq)] +pub struct Container { + pub kind: ContainerKind, + pub title: Option, + pub modifiers: Modifiers, + pub statements: Vec, + pub span: Span, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ContainerKind { + Window, + Box, + Section, + Row, + Column, +} + +impl fmt::Display for ContainerKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ContainerKind::Window => write!(f, "window"), + ContainerKind::Box => write!(f, "box"), + ContainerKind::Section => write!(f, "section"), + ContainerKind::Row => write!(f, "row"), + ContainerKind::Column => write!(f, "column"), + } + } +} + +/// Primitive elements (leaf nodes). +#[derive(Debug, Clone, PartialEq)] +pub enum Primitive { + Text { + content: String, + modifiers: Modifiers, + span: Span, + }, + Input { + modifiers: Modifiers, + span: Span, + }, + Checkbox { + label: String, + checked: bool, + span: Span, + }, + Radio { + label: String, + selected: bool, + span: Span, + }, + Select { + value: String, + modifiers: Modifiers, + span: Span, + }, + Button { + label: String, + modifiers: Modifiers, + span: Span, + }, + Link { + text: String, + span: Span, + }, + Code { + content: String, + span: Span, + }, + Raw { + content: String, + span: Span, + }, + Separator { + span: Span, + }, + Spacer { + span: Span, + }, + Progress { + value: u8, // 0-100 + span: Span, + }, + Alert { + alert_type: AlertType, + statements: Vec, + span: Span, + }, + Table(Table), + List(List), +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum AlertType { + Error, + Warn, + Info, +} + +impl fmt::Display for AlertType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + AlertType::Error => write!(f, "error"), + AlertType::Warn => write!(f, "warn"), + AlertType::Info => write!(f, "info"), + } + } +} + +/// Table structure with header and rows. +#[derive(Debug, Clone, PartialEq)] +pub struct Table { + pub header: Option, + pub rows: Vec, + pub modifiers: Modifiers, + pub span: Span, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct TableHeader { + pub columns: Vec, + pub span: Span, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct TableColumn { + pub label: String, + pub modifiers: Modifiers, + pub span: Span, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct TableRow { + pub cells: Vec, + pub span: Span, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct TableCell { + pub content: String, + pub modifiers: Modifiers, + pub span: Span, +} + +/// List with selectable items. +#[derive(Debug, Clone, PartialEq)] +pub struct List { + pub items: Vec, + pub span: Span, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct ListItem { + pub content: String, + pub selected: bool, + pub span: Span, +} + +/// Modifiers (attributes + flags). +#[derive(Debug, Clone, PartialEq, Default)] +pub struct Modifiers { + pub width: Option, + pub height: Option, + pub padding: Option, + pub gap: Option, + pub align: Option, + pub style: Option