use crate::span::Span;
#[derive(Debug)]
pub struct File {
pub defs: Option<DefsBlock>,
pub stmts: Vec<Stmt>,
}
#[derive(Debug)]
pub enum Stmt {
Node(ShapeInst),
Wire(WireDecl),
}
#[derive(Debug)]
pub struct DefsBlock {
pub entries: Vec<DefsEntry>,
pub span: Span,
}
#[derive(Debug)]
pub enum DefsEntry {
SceneConfig(SceneConfig),
WireConfig(WireConfig),
TypeDefaults(TypeDefaults),
VarOverride(VarOverride),
StyleDef(StyleDef),
ShapeDef(ShapeDef),
}
impl DefsEntry {
pub fn span(&self) -> Span {
match self {
DefsEntry::SceneConfig(s) => s.span,
DefsEntry::WireConfig(w) => w.span,
DefsEntry::TypeDefaults(t) => t.span,
DefsEntry::VarOverride(v) => v.span,
DefsEntry::StyleDef(s) => s.span,
DefsEntry::ShapeDef(s) => s.span,
}
}
}
#[derive(Debug)]
pub struct SceneConfig {
pub items: Vec<AttrItem>,
pub span: Span,
}
#[derive(Debug)]
pub struct WireConfig {
pub items: Vec<AttrItem>,
pub span: Span,
}
#[derive(Debug)]
pub struct TypeDefaults {
pub name: String,
pub items: Vec<AttrItem>,
pub span: Span,
}
#[derive(Debug)]
pub struct VarOverride {
pub name: String,
pub value: Value,
pub span: Span,
}
#[derive(Debug)]
pub struct StyleDef {
pub name: String,
pub items: Vec<AttrItem>,
pub span: Span,
}
#[derive(Debug)]
pub struct ShapeDef {
pub name: String,
pub base: TypeRef,
pub items: Vec<AttrItem>,
pub body: Option<Vec<BodyItem>>,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct ShapeInst {
pub id: Option<String>,
pub ty: TypeRef,
pub label: Option<String>,
pub href: Option<String>,
pub items: Vec<AttrItem>,
pub body: Option<Vec<BodyItem>>,
pub span: Span,
}
#[derive(Debug, Clone)]
pub enum BodyItem {
Inst(ShapeInst),
Wire(WireDecl),
}
#[derive(Debug, Clone, PartialEq)]
pub struct TypeRef {
pub name: String,
pub span: Span,
}
#[derive(Debug, Clone)]
pub enum AttrItem {
Attr(Attr),
Style(StyleRef),
}
#[derive(Debug, Clone)]
pub struct Attr {
pub name: String,
pub value: Value,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct StyleRef {
pub name: String,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct WireDecl {
pub chain: Vec<EndpointGroup>,
pub op: WireOp,
pub label: Option<String>,
pub items: Vec<AttrItem>,
pub body: Option<Vec<TextDecl>>,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct EndpointGroup {
pub endpoints: Vec<WireEndpoint>,
}
#[derive(Debug, Clone)]
pub struct WireEndpoint {
pub path: Vec<String>,
pub side: Option<Side>,
pub span: Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Side {
Top,
Bottom,
Left,
Right,
}
impl Side {
pub const ALL: [Side; 4] = [Side::Top, Side::Right, Side::Bottom, Side::Left];
pub fn parse(s: &str) -> Option<Self> {
Some(match s {
"top" => Self::Top,
"bottom" => Self::Bottom,
"left" => Self::Left,
"right" => Self::Right,
_ => return None,
})
}
pub fn index(self) -> u8 {
match self {
Side::Top => 0,
Side::Right => 1,
Side::Bottom => 2,
Side::Left => 3,
}
}
}
#[derive(Debug, Clone)]
pub struct TextDecl {
pub text: String,
pub items: Vec<AttrItem>,
pub span: Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct WireOp {
pub line: LineStyle,
pub start: WireMarker,
pub end: WireMarker,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LineStyle {
Solid, Dashed, Dotted, Wavy, }
impl LineStyle {
pub fn as_str(self) -> &'static str {
match self {
Self::Solid => "-",
Self::Dashed => "--",
Self::Dotted => "-.-",
Self::Wavy => "~",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum WireMarker {
#[default]
None,
Arrow, Crow, Dot, Diamond, }
impl WireMarker {
pub fn start_str(self) -> &'static str {
match self {
Self::None => "",
Self::Arrow => "<",
Self::Crow => ">",
Self::Dot => "*",
Self::Diamond => "<>",
}
}
pub fn end_str(self) -> &'static str {
match self {
Self::None => "",
Self::Arrow => ">",
Self::Crow => "<",
Self::Dot => "*",
Self::Diamond => "<>",
}
}
}
#[derive(Debug, Clone)]
pub enum Value {
Number(f64),
String(String),
Hex(String),
Ident(String),
Tuple(Vec<Value>),
List(Vec<Value>),
Call(FnCall),
RawCssVar(String), }
#[derive(Debug, Clone)]
pub struct FnCall {
pub name: String,
pub args: Vec<Value>,
pub span: Span,
}