gleam-kicad-sexpr/src/kicad_sexpr/token.gleam
Lily Rose 3f04932c2f
Some checks are pending
test / test (push) Waiting to run
Fix width and height order for size token
2025-07-26 01:25:46 +10:00

3065 lines
77 KiB
Gleam

import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/pair
import kicad_sexpr/decode.{type Decoder, type NextFn}
fn width(then next: NextFn(Float, a)) -> Decoder(a) {
decode.token_wrapper(named: "width", with: decode.float, then: next)
}
fn thickness(then next: NextFn(Float, a)) -> Decoder(a) {
decode.token_wrapper(named: "thickness", with: decode.float, then: next)
}
fn yes_no(then next: NextFn(Bool, a)) -> Decoder(a) {
decode.enum(with: [#("yes", True), #("no", False)], then: next)
}
fn allowed(then next: NextFn(Bool, a)) -> Decoder(a) {
decode.enum(with: [#("allowed", True), #("not_allowed", False)], then: next)
}
fn filled(then next: NextFn(Bool, a)) -> Decoder(a) {
decode.token_wrapper(named: "fill", with: yes_no, then: next)
}
fn angle(then next: NextFn(Float, a)) -> Decoder(a) {
decode.token_wrapper(named: "angle", with: decode.float, then: next)
}
fn corners(then next: NextFn(#(XY, XY, XY, XY), a)) -> Decoder(a) {
decode.token(named: "pts", then: next, with: {
use xy1 <- xy()
use xy2 <- xy()
use xy3 <- xy()
use xy4 <- xy()
decode.success(#(xy1, xy2, xy3, xy4))
})
}
fn margins(then next: NextFn(#(Float, Float, Float, Float), a)) -> Decoder(a) {
decode.token(
named: "margins",
with: {
use f1 <- decode.float()
use f2 <- decode.float()
use f3 <- decode.float()
use f4 <- decode.float()
decode.success(#(f1, f2, f3, f4))
},
then: next,
)
}
fn hide(then next: NextFn(Bool, a)) -> Decoder(a) {
decode.one_of(
decode.token_wrapper(named: "hide", with: yes_no, then: _),
or: [decode.flag("hide", then: _)],
then: next,
)
}
fn custom_xy(named name: String, then next: NextFn(XY, a)) -> Decoder(a) {
decode.token(named: name, then: next, with: {
use x <- decode.float()
use y <- decode.float()
decode.success(XY(x:, y:))
})
}
fn layers(then next: NextFn(List(Layer), a)) -> Decoder(a) {
decode.token(named: "layers", then: next, with: {
use layers <- decode.list(decode.name_string)
let layers = list.map(layers, Layer)
decode.success(layers)
})
}
pub type PositionIdentifier {
PositionIdentifier(
x: Float,
y: Float,
angle: Option(Float),
locked: Option(Bool),
)
}
pub fn position_identifier(
then next: NextFn(PositionIdentifier, a),
) -> Decoder(a) {
decode.token(named: "at", then: next, with: {
use x <- decode.float()
use y <- decode.float()
use angle <- decode.optional(decode.float)
use locked <- decode.optional(decode.enum(
[#("locked", True), #("unlocked", False)],
then: _,
))
decode.success(PositionIdentifier(x:, y:, angle:, locked:))
})
}
pub type XY {
XY(x: Float, y: Float)
}
pub fn xy(then next: NextFn(XY, a)) -> Decoder(a) {
decode.token(named: "xy", then: next, with: {
use x <- decode.float()
use y <- decode.float()
decode.success(XY(x:, y:))
})
}
pub type XYZ {
XYZ(x: Float, y: Float, z: Float)
}
pub fn xyz(then next: NextFn(XYZ, a)) -> Decoder(a) {
decode.token(named: "xyz", then: next, with: {
use x <- decode.float()
use y <- decode.float()
use z <- decode.float()
decode.success(XYZ(x:, y:, z:))
})
}
pub type Line {
Line(points: Points)
}
pub fn line(then next: NextFn(Line, a)) -> Decoder(a) {
decode.token(named: "polyline", then: next, with: {
use points <- points()
decode.success(Line(points:))
})
}
pub type Rectangle {
Rectangle(start: XY, end: XY)
}
pub fn rectangle(then next: NextFn(Rectangle, a)) -> Decoder(a) {
decode.token(named: "rectangle", then: next, with: {
use start <- custom_xy("start")
use end <- custom_xy("end")
decode.success(Rectangle(start:, end:))
})
}
pub type Circle {
Circle(center: XY, radius: Float)
}
pub fn circle(then next: NextFn(Circle, a)) -> Decoder(a) {
decode.token(named: "circle", then: next, with: {
use center <- custom_xy("center")
use radius <- decode.token_wrapper(named: "radius", with: decode.float)
decode.success(Circle(center:, radius:))
})
}
pub type Arc {
Arc(start: XY, mid: XY, end: XY)
}
pub fn arc(then next: NextFn(Arc, a)) -> Decoder(a) {
decode.token(named: "arc", then: next, with: {
use start <- custom_xy("start")
use mid <- custom_xy("mid")
use end <- custom_xy("end")
decode.success(Arc(start:, mid:, end:))
})
}
pub type Curve {
Curve(points: Points)
}
pub fn curve(then next: NextFn(Curve, a)) -> Decoder(a) {
decode.token(named: "bezier", then: next, with: {
use points <- points()
decode.success(Curve(points:))
})
}
pub type PolyPoint {
XYPolyPoint(XY)
ArcPolyPoint(Arc)
}
pub fn poly_point(then next: NextFn(PolyPoint, a)) -> Decoder(a) {
decode.one_of(
xy |> decode.map(XYPolyPoint),
or: [arc |> decode.map(ArcPolyPoint)],
then: next,
)
}
pub type PolyPoints {
PolyPoints(points: List(PolyPoint))
}
pub fn poly_points(then next: NextFn(PolyPoints, a)) -> Decoder(a) {
decode.token(named: "pts", then: next, with: {
use points <- decode.list(poly_point)
decode.success(PolyPoints(points:))
})
}
pub type Points {
Points(points: List(XY))
}
pub fn points(then next: NextFn(Points, a)) -> Decoder(a) {
decode.token(named: "pts", then: next, with: {
use points <- decode.list(xy)
decode.success(Points(points:))
})
}
pub type StrokeType {
DashStrokeType
DashDotStrokeType
DashDotDotStrokeType
DotStrokeType
DefaultStrokeType
SolidStrokeType
}
pub fn stroke_type(then next: NextFn(StrokeType, a)) -> Decoder(a) {
decode.token(named: "type", then: next, with: {
use stroke_type <- decode.enum([
#("dash", DashStrokeType),
#("dash_dot", DashDotStrokeType),
#("dash_dot_dot", DashDotDotStrokeType),
#("dot", DotStrokeType),
#("default", DefaultStrokeType),
#("solid", SolidStrokeType),
])
decode.success(stroke_type)
})
}
pub type Color {
Color(r: Float, g: Float, b: Float, a: Float)
}
pub fn color(then next: NextFn(Color, a)) -> Decoder(a) {
decode.token(named: "color", then: next, with: {
use r <- decode.float()
use g <- decode.float()
use b <- decode.float()
use a <- decode.float()
decode.success(Color(r:, g:, b:, a:))
})
}
pub type Stroke {
Stroke(width: Float, type_: StrokeType, color: Option(Color))
}
pub fn stroke(then next: NextFn(Stroke, a)) -> Decoder(a) {
decode.token(named: "stroke", then: next, with: {
use width <- width()
use type_ <- stroke_type()
use color <- decode.optional(color)
decode.success(Stroke(width:, type_:, color:))
})
}
pub type FillType {
NoFill
SolidFillType
OutlineFillType
BackgroundFillType
}
pub fn fill_type(then next: NextFn(FillType, a)) -> Decoder(a) {
decode.enum(
[
#("none", NoFill),
#("solid", SolidFillType),
#("outline", OutlineFillType),
#("background", BackgroundFillType),
],
then: next,
)
}
pub type Fill {
Fill(type_: FillType)
}
pub fn fill(then next: NextFn(Fill, a)) -> Decoder(a) {
decode.token(named: "fill", then: next, with: {
use type_ <- decode.one_of(
decode.token_wrapper(named: "type", with: fill_type, then: _),
or: [fill_type],
)
decode.success(Fill(type_:))
})
}
pub type Size {
Size(width: Float, height: Float)
}
pub fn size(then next: NextFn(Size, a)) -> Decoder(a) {
decode.token(named: "size", then: next, with: {
use width <- decode.float()
use height <- decode.float()
decode.success(Size(width:, height:))
})
}
pub type Font {
Font(
face: Option(String),
size: Size,
thickness: Option(Float),
bold: Option(Bool),
italic: Option(Bool),
line_spacing: Option(Float),
)
}
pub fn font(then next: NextFn(Font, a)) -> Decoder(a) {
decode.token(named: "font", then: next, with: {
use face <- decode.optional(decode.token_wrapper(
named: "face",
with: decode.string,
then: _,
))
use size <- size()
use thickness <- decode.optional(thickness)
use bold <- decode.optional(decode.one_of(
decode.token_wrapper(named: "bold", with: yes_no, then: _),
or: [decode.flag("bold", then: _)],
then: _,
))
use italic <- decode.optional(decode.one_of(
decode.token_wrapper(named: "italic", with: yes_no, then: _),
or: [decode.flag("italic", then: _)],
then: _,
))
use line_spacing <- decode.optional(decode.token_wrapper(
named: "line_spacing",
with: decode.float,
then: _,
))
decode.success(Font(face:, size:, thickness:, bold:, italic:, line_spacing:))
})
}
pub type Horizontal {
Left
Right
}
pub fn horizontal(then next: NextFn(Horizontal, a)) -> Decoder(a) {
decode.enum(then: next, with: [#("left", Left), #("right", Right)])
}
pub type Vertical {
Top
Bottom
}
pub fn vertical(then next: NextFn(Vertical, a)) -> Decoder(a) {
decode.enum(then: next, with: [#("top", Top), #("bottom", Bottom)])
}
pub type Justify {
Justify(
horizontal: Option(Horizontal),
vertical: Option(Vertical),
mirror: Bool,
)
}
pub fn justify(then next: NextFn(Justify, a)) -> Decoder(a) {
decode.token(named: "justify", then: next, with: {
use horizontal <- decode.optional(horizontal)
use vertical <- decode.optional(vertical)
use mirror <- decode.flag("mirror")
decode.success(Justify(horizontal:, vertical:, mirror:))
})
}
pub type Effects {
Effects(font: Font, justify: Option(Justify), hide: Option(Bool))
}
pub fn effects(then next: NextFn(Effects, a)) -> Decoder(a) {
decode.token(named: "effects", then: next, with: {
use font <- font()
use justify <- decode.optional(justify)
use hide <- decode.optional(hide)
decode.success(Effects(font:, justify:, hide:))
})
}
pub type PaperSize {
A0PaperSize
A1PaperSize
A2PaperSize
A3PaperSize
A4PaperSize
A5PaperSize
APaperSize
BPaperSize
CPaperSize
DPaperSize
EPaperSize
CustomPaperSize(width: Float, height: Float)
}
pub fn paper_size(then next: NextFn(PaperSize, a)) -> Decoder(a) {
decode.one_of(
decode.enum(then: _, with: [
#("A0", A0PaperSize),
#("A1", A1PaperSize),
#("A2", A2PaperSize),
#("A3", A3PaperSize),
#("A4", A4PaperSize),
#("A5", A5PaperSize),
#("A", APaperSize),
#("B", BPaperSize),
#("C", CPaperSize),
#("D", DPaperSize),
#("E", EPaperSize),
]),
or: [
decode.of(then: _, with: {
use width <- decode.float()
use height <- decode.float()
decode.success(CustomPaperSize(width:, height:))
}),
],
then: next,
)
}
pub type Paper {
Paper(size: PaperSize, portrait: Bool)
}
pub fn paper(then next: NextFn(Paper, a)) -> Decoder(a) {
decode.token(named: "paper", then: next, with: {
use size <- paper_size()
use portrait <- decode.flag("portrait")
decode.success(Paper(size:, portrait:))
})
}
pub type Comment {
Comment(number: Int, comment: String)
}
pub fn comment(then next: NextFn(Comment, a)) -> Decoder(a) {
decode.token(named: "comment", then: next, with: {
use number <- decode.int()
use comment <- decode.string()
decode.success(Comment(number:, comment:))
})
}
pub type TitleBlock {
TitleBlock(
title: String,
date: String,
revision: String,
company: String,
comment: Comment,
)
}
pub fn title_block(then next: NextFn(TitleBlock, a)) -> Decoder(a) {
decode.token(named: "title_block", then: next, with: {
use title <- decode.token_wrapper(named: "title", with: decode.string)
use date <- decode.token_wrapper(named: "date", with: decode.string)
use revision <- decode.token_wrapper(named: "rev", with: decode.string)
use company <- decode.token_wrapper(named: "company", with: decode.string)
use comment <- comment()
decode.success(TitleBlock(title:, date:, revision:, company:, comment:))
})
}
pub type Property {
Property(key: String, value: String)
}
pub fn property(then next: NextFn(Property, a)) -> Decoder(a) {
decode.token(named: "property", then: next, with: {
use key <- decode.string()
use value <- decode.string()
decode.success(Property(key:, value:))
})
}
pub type Uuid {
Uuid(uuid: String)
}
pub fn uuid(then next: NextFn(Uuid, a)) -> Decoder(a) {
decode.token(named: "uuid", then: next, with: {
use uuid <- decode.string()
decode.success(Uuid(uuid:))
})
}
pub type Timestamp {
Timestamp(ts: String)
}
pub fn timestamp(then next: NextFn(Timestamp, a)) -> Decoder(a) {
decode.token(named: "tstamp", then: next, with: {
use ts <- decode.string()
decode.success(Timestamp(ts:))
})
}
pub type Layer {
Layer(layer: String)
}
pub fn layer(then next: NextFn(Layer, a)) -> Decoder(a) {
decode.token(named: "layer", then: next, with: {
use layer <- decode.name_string()
decode.success(Layer(layer:))
})
}
pub type Image {
Image(
position: PositionIdentifier,
scale: Option(Float),
layer: Option(Layer),
uuid: Option(Uuid),
data: String,
)
}
pub fn image(then next: NextFn(Image, a)) -> Decoder(a) {
decode.token(named: "image", then: next, with: {
use position <- position_identifier()
use scale <- decode.optional(decode.token_wrapper(
named: "scale",
with: decode.float,
then: _,
))
use layer <- decode.optional(layer)
use uuid <- decode.optional(uuid)
use data <- decode.string()
decode.success(Image(position:, scale:, layer:, uuid:, data:))
})
}
pub type ConnectionType {
NoConnection
ThermalConnectionType
SolidFillConnectionType
}
pub fn connection_type(then next: NextFn(ConnectionType, a)) -> Decoder(a) {
decode.int_enum(then: next, with: [
NoConnection,
ThermalConnectionType,
SolidFillConnectionType,
])
}
pub type FootprintProperty {
FootprintProperty(
key: String,
value: String,
position: PositionIdentifier,
unlocked: Option(Bool),
layer: Layer,
hide: Option(Bool),
uuid: Option(Uuid),
effects: Effects,
)
}
pub fn footprint_property(then next: NextFn(FootprintProperty, a)) -> Decoder(a) {
decode.token(named: "property", then: next, with: {
use key <- decode.string()
use value <- decode.string()
use position <- position_identifier()
use unlocked <- decode.optional(decode.token_wrapper(
named: "unlocked",
with: yes_no,
then: _,
))
use layer <- layer()
use hide <- decode.optional(hide)
use uuid <- decode.optional(uuid)
use effects <- effects()
decode.success(FootprintProperty(
key:,
value:,
position:,
unlocked:,
layer:,
hide:,
uuid:,
effects:,
))
})
}
pub type FootprintAttributeType {
SmdAttributeType
ThroughHoleAttributeType
}
pub fn footprint_attribute_type(
then next: NextFn(FootprintAttributeType, a),
) -> Decoder(a) {
decode.enum(then: next, with: [
#("smd", SmdAttributeType),
#("through_hole", ThroughHoleAttributeType),
])
}
pub type FootprintAttributes {
FootprintAttributes(
type_: Option(FootprintAttributeType),
board_only: Bool,
exclude_from_pos_files: Bool,
exclude_from_bom: Bool,
allow_soldermask_bridges: Bool,
allow_missing_courtyard: Bool,
)
}
pub fn footprint_attributes(
then next: NextFn(FootprintAttributes, a),
) -> Decoder(a) {
decode.token(named: "attr", then: next, with: {
use type_ <- decode.optional(footprint_attribute_type)
use board_only <- decode.flag("board_only")
use exclude_from_pos_files <- decode.flag("exclude_from_pos_files")
use exclude_from_bom <- decode.flag("exclude_from_bom")
use allow_soldermask_bridges <- decode.flag("allow_soldermask_bridges")
use allow_missing_courtyard <- decode.flag("allow_missing_courtyard")
decode.success(FootprintAttributes(
type_:,
board_only:,
exclude_from_pos_files:,
exclude_from_bom:,
allow_soldermask_bridges:,
allow_missing_courtyard:,
))
})
}
pub type FootprintTextType {
ReferenceTextType
ValueTextType
UserTextType
}
pub fn footprint_text_type(
then next: NextFn(FootprintTextType, a),
) -> Decoder(a) {
decode.enum(then: next, with: [
#("reference", ReferenceTextType),
#("value", ValueTextType),
#("user", UserTextType),
])
}
pub type FootprintText {
FootprintText(
type_: FootprintTextType,
text: String,
position: PositionIdentifier,
unlocked: Option(Bool),
layer: Layer,
hide: Option(Bool),
uuid: Option(Uuid),
effects: Effects,
timestamp: Option(Timestamp),
)
}
pub fn footprint_text(then next: NextFn(FootprintText, a)) -> Decoder(a) {
decode.token(named: "fp_text", then: next, with: {
use type_ <- footprint_text_type()
use text <- decode.name_string()
use position <- position_identifier()
use unlocked <- decode.optional(decode.token_wrapper(
named: "unlocked",
with: yes_no,
then: _,
))
use layer <- layer()
use hide <- decode.optional(hide)
use uuid <- decode.optional(uuid)
use effects <- effects()
use timestamp <- decode.optional(timestamp)
decode.success(FootprintText(
type_:,
text:,
position:,
unlocked:,
layer:,
hide:,
uuid:,
effects:,
timestamp:,
))
})
}
pub type FootprintTextBox {
FootprintTextBox(
locked: Bool,
text: String,
start: Option(XY),
end: Option(XY),
corners: Option(#(XY, XY, XY, XY)),
margins: Option(#(Float, Float, Float, Float)),
angle: Option(Float),
layer: Layer,
uuid: Option(Uuid),
effects: Effects,
border: Option(Bool),
stroke: Option(Stroke),
render_cache: Option(Nil),
timestamp: Option(Timestamp),
)
}
pub fn footprint_text_box(then next: NextFn(FootprintTextBox, a)) -> Decoder(a) {
decode.token(named: "fp_text_box", then: next, with: {
use locked <- decode.flag("locked")
use text <- decode.string()
use start <- decode.optional(custom_xy("start", then: _))
use end <- decode.optional(custom_xy("end", then: _))
use corners <- decode.optional(corners)
use margins <- decode.optional(margins)
use angle <- decode.optional(angle)
use layer <- layer()
use uuid <- decode.optional(uuid)
use effects <- effects()
use border <- decode.optional(decode.token_wrapper(
named: "border",
with: yes_no,
then: _,
))
use stroke <- decode.optional(stroke)
let render_cache = None
use timestamp <- decode.optional(timestamp)
decode.success(FootprintTextBox(
locked:,
text:,
start:,
end:,
corners:,
margins:,
angle:,
layer:,
uuid:,
effects:,
border:,
stroke:,
render_cache:,
timestamp:,
))
})
}
pub type FootprintLine {
FootprintLine(
start: XY,
end: XY,
stroke: Option(Stroke),
layer: Layer,
width: Option(Float),
locked: Bool,
uuid: Option(Uuid),
timestamp: Option(Timestamp),
)
}
pub fn footprint_line(then next: NextFn(FootprintLine, a)) -> Decoder(a) {
decode.token(named: "fp_line", then: next, with: {
use start <- custom_xy("start")
use end <- custom_xy("end")
use stroke <- decode.optional(stroke)
use layer <- layer()
use width <- decode.optional(width)
use locked <- decode.flag("locked")
use uuid <- decode.optional(uuid)
use timestamp <- decode.optional(timestamp)
decode.success(FootprintLine(
start:,
end:,
stroke:,
layer:,
width:,
locked:,
uuid:,
timestamp:,
))
})
}
pub type FootprintRectangle {
FootprintRectangle(
start: XY,
end: XY,
stroke: Option(Stroke),
filled: Option(Bool),
layer: Layer,
fill: Option(Fill),
width: Option(Float),
locked: Bool,
uuid: Option(Uuid),
timestamp: Option(Timestamp),
)
}
pub fn footprint_rectangle(
then next: NextFn(FootprintRectangle, a),
) -> Decoder(a) {
decode.token(named: "fp_rect", then: next, with: {
use start <- custom_xy("start")
use end <- custom_xy("end")
use stroke <- decode.optional(stroke)
use filled <- decode.optional(filled)
use layer <- layer()
use fill_a <- decode.optional(fill)
use width <- decode.optional(width)
use fill_b <- decode.optional(fill)
let fill = fill_a |> option.or(fill_b)
use locked <- decode.flag("locked")
use uuid <- decode.optional(uuid)
use timestamp <- decode.optional(timestamp)
decode.success(FootprintRectangle(
start:,
end:,
stroke:,
filled:,
layer:,
fill:,
width:,
locked:,
uuid:,
timestamp:,
))
})
}
pub type FootprintCircle {
FootprintCircle(
center: XY,
end: XY,
stroke: Option(Stroke),
filled: Option(Bool),
layer: Layer,
fill: Option(Fill),
width: Option(Float),
locked: Bool,
uuid: Option(Uuid),
timestamp: Option(Timestamp),
)
}
pub fn footprint_circle(then next: NextFn(FootprintCircle, a)) -> Decoder(a) {
decode.token(named: "fp_circle", then: next, with: {
use center <- custom_xy("center")
use end <- custom_xy("end")
use stroke <- decode.optional(stroke)
use filled <- decode.optional(filled)
use layer <- layer()
use fill_a <- decode.optional(fill)
use width <- decode.optional(width)
use fill_b <- decode.optional(fill)
let fill = fill_a |> option.or(fill_b)
use locked <- decode.flag("locked")
use uuid <- decode.optional(uuid)
use timestamp <- decode.optional(timestamp)
decode.success(FootprintCircle(
center:,
end:,
stroke:,
filled:,
layer:,
fill:,
width:,
locked:,
uuid:,
timestamp:,
))
})
}
pub type FootprintArc {
FootprintArc(
start: XY,
mid: XY,
end: XY,
stroke: Option(Stroke),
layer: Layer,
width: Option(Float),
locked: Bool,
uuid: Option(Uuid),
timestamp: Option(Timestamp),
)
}
pub fn footprint_arc(then next: NextFn(FootprintArc, a)) -> Decoder(a) {
decode.token(named: "fp_arc", then: next, with: {
use start <- custom_xy("start")
use mid <- custom_xy("mid")
use end <- custom_xy("end")
use stroke <- decode.optional(stroke)
use layer <- layer()
use width <- decode.optional(width)
use locked <- decode.flag("locked")
use uuid <- decode.optional(uuid)
use timestamp <- decode.optional(timestamp)
decode.success(FootprintArc(
start:,
mid:,
end:,
stroke:,
layer:,
width:,
locked:,
uuid:,
timestamp:,
))
})
}
pub type FootprintPolygon {
FootprintPolygon(
points: PolyPoints,
stroke: Option(Stroke),
filled: Option(Bool),
layer: Layer,
fill: Option(Fill),
width: Option(Float),
locked: Bool,
uuid: Option(Uuid),
timestamp: Option(Timestamp),
)
}
pub fn footprint_polygon(then next: NextFn(FootprintPolygon, a)) -> Decoder(a) {
decode.token(named: "fp_poly", then: next, with: {
use points <- poly_points()
use stroke <- decode.optional(stroke)
use filled <- decode.optional(filled)
use layer <- layer()
use fill_a <- decode.optional(fill)
use width <- decode.optional(width)
use fill_b <- decode.optional(fill)
let fill = fill_a |> option.or(fill_b)
use locked <- decode.flag("locked")
use uuid <- decode.optional(uuid)
use timestamp <- decode.optional(timestamp)
decode.success(FootprintPolygon(
points:,
stroke:,
filled:,
layer:,
fill:,
width:,
locked:,
uuid:,
timestamp:,
))
})
}
pub type FootprintCurve {
FootprintCurve(
points: Points,
stroke: Option(Stroke),
layer: Layer,
width: Option(Float),
locked: Bool,
uuid: Option(Uuid),
timestamp: Option(Timestamp),
)
}
pub fn footprint_curve(then next: NextFn(FootprintCurve, a)) -> Decoder(a) {
decode.token(named: "fp_curve", then: next, with: {
use points <- points()
use stroke <- decode.optional(stroke)
use layer <- layer()
use width <- decode.optional(width)
use locked <- decode.flag("locked")
use uuid <- decode.optional(uuid)
use timestamp <- decode.optional(timestamp)
decode.success(FootprintCurve(
points:,
stroke:,
layer:,
width:,
locked:,
uuid:,
timestamp:,
))
})
}
pub type DimensionType {
AlignedDimensionType
LeaderDimensionType
CenterDimensionType
OrthogonalDimensionType
RadialDimensionType
}
pub fn dimension_type(then next: NextFn(DimensionType, a)) -> Decoder(a) {
decode.enum(
with: [
#("aligned", AlignedDimensionType),
#("leader", LeaderDimensionType),
#("center", CenterDimensionType),
#("orthogonal", OrthogonalDimensionType),
#("radial", RadialDimensionType),
],
then: next,
)
}
pub type Unit {
InchesUnit
MilsUnit
MillimetersUnit
AutomaticUnit
}
pub fn unit(then next: NextFn(Unit, a)) -> Decoder(a) {
decode.int_enum(
with: [InchesUnit, MilsUnit, MillimetersUnit, AutomaticUnit],
then: next,
)
}
pub type UnitFormat {
NoSuffixUnitFormat
BareSuffixUnitFormat
WrapSuffixUnitFormat
}
pub fn unit_format(then next: NextFn(UnitFormat, a)) -> Decoder(a) {
decode.int_enum(
with: [NoSuffixUnitFormat, BareSuffixUnitFormat, WrapSuffixUnitFormat],
then: next,
)
}
pub type DimensionFormat {
DimensionFormat(
prefix: Option(String),
suffix: Option(String),
unit: Unit,
unit_format: UnitFormat,
precision: Int,
override_value: Option(String),
suppress_zeros: Option(Bool),
)
}
pub fn dimension_format(then next: NextFn(DimensionFormat, a)) -> Decoder(a) {
decode.token(named: "format", then: next, with: {
use prefix <- decode.optional(decode.token_wrapper(
named: "prefix",
with: decode.string,
then: _,
))
use suffix <- decode.optional(decode.token_wrapper(
named: "suffix",
with: decode.string,
then: _,
))
use unit <- decode.token_wrapper(named: "units", with: unit)
use unit_format <- decode.token_wrapper(
named: "units_format",
with: unit_format,
)
use precision <- decode.token_wrapper(named: "precision", with: decode.int)
use override_value <- decode.optional(decode.token_wrapper(
named: "override_value",
with: decode.string,
then: _,
))
use suppress_zeros <- decode.optional(decode.token_wrapper(
named: "suppress_zeros",
with: yes_no,
then: _,
))
decode.success(DimensionFormat(
prefix:,
suffix:,
unit:,
unit_format:,
precision:,
override_value:,
suppress_zeros:,
))
})
}
pub type TextPositionMode {
OutsideTextPositionMode
InlineTextPositionMode
ManualTextPositionMode
}
pub fn text_position_mode(then next: NextFn(TextPositionMode, a)) -> Decoder(a) {
decode.int_enum(
with: [
OutsideTextPositionMode,
InlineTextPositionMode,
ManualTextPositionMode,
],
then: next,
)
}
pub type ArrowDirection {
OutwardArrowDirection
InwardArrowDirection
}
pub fn arrow_direction(then next: NextFn(ArrowDirection, a)) -> Decoder(a) {
decode.enum(
with: [
#("outward", OutwardArrowDirection),
#("inward", InwardArrowDirection),
],
then: next,
)
}
pub type TextFrameType {
NoFrame
RectangleFrameType
CircleFrameType
RoundedRectangleFrameType
}
pub fn text_frame_type(then next: NextFn(TextFrameType, a)) -> Decoder(a) {
decode.int_enum(
with: [
NoFrame,
RectangleFrameType,
CircleFrameType,
RoundedRectangleFrameType,
],
then: next,
)
}
pub type DimensionStyle {
DimensionStyle(
thickness: Float,
arrow_length: Float,
text_position_mode: TextPositionMode,
arrow_direction: Option(ArrowDirection),
extension_height: Option(Float),
text_frame_type: Option(TextFrameType),
extension_offset: Option(Float),
keep_text_aligned: Option(Bool),
)
}
pub fn dimension_style(then next: NextFn(DimensionStyle, a)) -> Decoder(a) {
decode.token(named: "style", then: next, with: {
use thickness <- thickness()
use arrow_length <- decode.token_wrapper(
named: "arrow_length",
with: decode.float,
)
use text_position_mode <- decode.token_wrapper(
named: "text_position_mode",
with: text_position_mode,
)
use arrow_direction <- decode.optional(decode.token_wrapper(
named: "arrow_direction",
with: arrow_direction,
then: _,
))
use extension_height <- decode.optional(decode.token_wrapper(
named: "extension_height",
with: decode.float,
then: _,
))
use text_frame_type <- decode.optional(decode.token_wrapper(
named: "text_frame",
with: text_frame_type,
then: _,
))
use extension_offset <- decode.optional(decode.token_wrapper(
named: "extension_offset",
with: decode.float,
then: _,
))
use keep_text_aligned <- decode.optional(decode.token_wrapper(
named: "keep_text_aligned",
with: yes_no,
then: _,
))
decode.success(DimensionStyle(
thickness:,
arrow_length:,
text_position_mode:,
arrow_direction:,
extension_height:,
text_frame_type:,
extension_offset:,
keep_text_aligned:,
))
})
}
pub type Dimension {
Dimension(
locked: Bool,
type_: DimensionType,
layer: Layer,
uuid: Option(Uuid),
start: XY,
end: XY,
height: Option(Float),
orientation: Option(Float),
leader_length: Option(Float),
format: Option(DimensionFormat),
style: DimensionStyle,
text: Option(GraphicalText),
)
}
pub fn dimension(then next: NextFn(Dimension, a)) -> Decoder(a) {
decode.token(named: "dimension", then: next, with: {
use locked <- decode.flag("locked")
use type_ <- decode.token_wrapper(named: "type", with: dimension_type)
use layer <- layer()
use uuid <- decode.optional(uuid)
use #(start, end) <- decode.token(named: "pts", with: {
use xy1 <- xy()
use xy2 <- xy()
decode.success(#(xy1, xy2))
})
use height <- decode.optional(decode.token_wrapper(
named: "height",
with: decode.float,
then: _,
))
use orientation <- decode.optional(decode.token_wrapper(
named: "orientation",
with: decode.float,
then: _,
))
use leader_length <- decode.optional(decode.token_wrapper(
named: "leader_length",
with: decode.float,
then: _,
))
use format <- decode.optional(dimension_format)
use style <- dimension_style()
use text <- decode.optional(graphical_text)
decode.success(Dimension(
locked:,
type_:,
layer:,
uuid:,
start:,
end:,
height:,
orientation:,
leader_length:,
format:,
style:,
text:,
))
})
}
pub type FootprintGraphicItem {
TextFootprintGraphicItem(FootprintText)
TextBoxFootprintGraphicItem(FootprintTextBox)
LineFootprintGraphicItem(FootprintLine)
RectangleFootprintGraphicItem(FootprintRectangle)
CircleFootprintGraphicItem(FootprintCircle)
ArcFootprintGraphicItem(FootprintArc)
PolygonFootprintGraphicItem(FootprintPolygon)
CurveFootprintGraphicItem(FootprintCurve)
DimensionFootprintGraphicItem(Dimension)
}
pub fn footprint_graphic_item(
then next: NextFn(FootprintGraphicItem, a),
) -> Decoder(a) {
decode.one_of(
footprint_text |> decode.map(TextFootprintGraphicItem),
or: [
footprint_text_box |> decode.map(TextBoxFootprintGraphicItem),
footprint_line |> decode.map(LineFootprintGraphicItem),
footprint_rectangle |> decode.map(RectangleFootprintGraphicItem),
footprint_circle |> decode.map(CircleFootprintGraphicItem),
footprint_arc |> decode.map(ArcFootprintGraphicItem),
footprint_polygon |> decode.map(PolygonFootprintGraphicItem),
footprint_curve |> decode.map(CurveFootprintGraphicItem),
dimension |> decode.map(DimensionFootprintGraphicItem),
],
then: next,
)
}
pub type GraphicalTextLayer {
GraphicalTextLayer(layer: String, knockout: Bool)
}
pub fn graphical_text_layer(
then next: NextFn(GraphicalTextLayer, a),
) -> Decoder(a) {
decode.token(named: "layer", then: next, with: {
use layer <- decode.string()
use knockout <- decode.flag("knockout")
decode.success(GraphicalTextLayer(layer:, knockout:))
})
}
pub type GraphicalText {
GraphicalText(
text: String,
position: PositionIdentifier,
layer: Option(GraphicalTextLayer),
uuid: Option(Uuid),
effects: Effects,
)
}
pub fn graphical_text(then next: NextFn(GraphicalText, a)) -> Decoder(a) {
decode.token(named: "gr_text", then: next, with: {
use text <- decode.string()
use position <- position_identifier()
use layer <- decode.optional(graphical_text_layer)
use uuid <- decode.optional(uuid)
use effects <- effects()
decode.success(GraphicalText(text:, position:, layer:, uuid:, effects:))
})
}
pub type GraphicalTextBox {
GraphicalTextBox(
locked: Bool,
text: String,
start: Option(XY),
end: Option(XY),
corners: Option(#(XY, XY, XY, XY)),
angle: Option(Float),
layer: Option(Layer),
uuid: Option(Uuid),
effects: Effects,
stroke: Option(Stroke),
render_cache: Option(Nil),
)
}
pub fn graphical_text_box(then next: NextFn(GraphicalTextBox, a)) -> Decoder(a) {
decode.token(named: "gr_text_box", then: next, with: {
use locked <- decode.flag("locked")
use text <- decode.string()
use start <- decode.optional(custom_xy("start", then: _))
use end <- decode.optional(custom_xy("end", then: _))
use corners <- decode.optional(corners)
use angle <- decode.optional(angle)
use layer <- decode.optional(layer)
use uuid <- decode.optional(uuid)
use effects <- effects()
use stroke <- decode.optional(stroke)
let render_cache = None
decode.success(GraphicalTextBox(
locked:,
text:,
start:,
end:,
corners:,
angle:,
layer:,
uuid:,
effects:,
stroke:,
render_cache:,
))
})
}
pub type GraphicalLine {
GraphicalLine(
start: XY,
end: XY,
angle: Option(Float),
layer: Option(Layer),
width: Float,
uuid: Option(Uuid),
)
}
pub fn graphical_line(then next: NextFn(GraphicalLine, a)) -> Decoder(a) {
decode.token(named: "gr_line", then: next, with: {
use start <- custom_xy("start")
use end <- custom_xy("end")
use angle <- decode.optional(angle)
use layer <- decode.optional(layer)
use width <- width()
use uuid <- decode.optional(uuid)
decode.success(GraphicalLine(start:, end:, angle:, layer:, width:, uuid:))
})
}
pub type GraphicalRectangle {
GraphicalRectangle(
start: XY,
end: XY,
layer: Option(Layer),
width: Float,
fill: Option(Bool),
uuid: Option(Uuid),
)
}
pub fn graphical_rectangle(
then next: NextFn(GraphicalRectangle, a),
) -> Decoder(a) {
decode.token(named: "gr_rect", then: next, with: {
use start <- custom_xy("start")
use end <- custom_xy("end")
use layer <- decode.optional(layer)
use width <- width()
use fill <- decode.optional(filled)
use uuid <- decode.optional(uuid)
decode.success(GraphicalRectangle(
start:,
end:,
layer:,
width:,
fill:,
uuid:,
))
})
}
pub type GraphicalCircle {
GraphicalCircle(
center: XY,
end: XY,
layer: Option(Layer),
width: Float,
fill: Option(Bool),
uuid: Option(Uuid),
)
}
pub fn graphical_circle(then next: NextFn(GraphicalCircle, a)) -> Decoder(a) {
decode.token(named: "gr_circle", then: next, with: {
use center <- custom_xy("center")
use end <- custom_xy("end")
use layer <- decode.optional(layer)
use width <- width()
use fill <- decode.optional(filled)
use uuid <- decode.optional(uuid)
decode.success(GraphicalCircle(center:, end:, layer:, width:, fill:, uuid:))
})
}
pub type GraphicalArc {
GraphicalArc(
start: XY,
mid: XY,
end: XY,
layer: Option(Layer),
width: Float,
uuid: Option(Uuid),
)
}
pub fn graphical_arc(then next: NextFn(GraphicalArc, a)) -> Decoder(a) {
decode.token(named: "gr_arc", then: next, with: {
use start <- custom_xy("start")
use mid <- custom_xy("mid")
use end <- custom_xy("end")
use layer <- decode.optional(layer)
use width <- width()
use uuid <- decode.optional(uuid)
decode.success(GraphicalArc(start:, mid:, end:, layer:, width:, uuid:))
})
}
pub type GraphicalPolygon {
GraphicalPolygon(
points: PolyPoints,
layer: Option(Layer),
width: Float,
fill: Option(Bool),
uuid: Option(Uuid),
)
}
pub fn graphical_polygon(then next: NextFn(GraphicalPolygon, a)) -> Decoder(a) {
decode.token(named: "gr_poly", then: next, with: {
use points <- poly_points()
use layer <- decode.optional(layer)
use width <- width()
use fill <- decode.optional(filled)
use uuid <- decode.optional(uuid)
decode.success(GraphicalPolygon(points:, layer:, width:, fill:, uuid:))
})
}
pub type GraphicalCurve {
GraphicalCurve(
points: Points,
layer: Option(Layer),
width: Float,
uuid: Option(Uuid),
)
}
pub fn graphical_curve(then next: NextFn(GraphicalCurve, a)) -> Decoder(a) {
decode.token(named: "bezier", then: next, with: {
use points <- points()
use layer <- decode.optional(layer)
use width <- width()
use uuid <- decode.optional(uuid)
decode.success(GraphicalCurve(points:, layer:, width:, uuid:))
})
}
pub type GraphicalBoundingBox {
GraphicalBoundingBox(start: XY, end: XY)
}
pub fn graphical_bounding_box(
then next: NextFn(GraphicalBoundingBox, a),
) -> Decoder(a) {
decode.token(named: "gr_bbox", then: next, with: {
use start <- custom_xy("start")
use end <- custom_xy("end")
decode.success(GraphicalBoundingBox(start:, end:))
})
}
pub type GraphicItem {
TextGraphicItem(GraphicalText)
TextBoxGraphicItem(GraphicalTextBox)
LineGraphicItem(GraphicalLine)
RectangleGraphicItem(GraphicalRectangle)
CircleGraphicItem(GraphicalCircle)
ArcGraphicItem(GraphicalArc)
PolygonGraphicItem(GraphicalPolygon)
CurveGraphicItem(GraphicalCurve)
DimensionGraphicItem(Dimension)
BoundingBoxGraphicItem(GraphicalBoundingBox)
}
pub fn graphic_item(then next: NextFn(GraphicItem, a)) -> Decoder(a) {
decode.one_of(
graphical_text |> decode.map(TextGraphicItem),
or: [
graphical_text_box |> decode.map(TextBoxGraphicItem),
graphical_line |> decode.map(LineGraphicItem),
graphical_rectangle |> decode.map(RectangleGraphicItem),
graphical_circle |> decode.map(CircleGraphicItem),
graphical_arc |> decode.map(ArcGraphicItem),
graphical_polygon |> decode.map(PolygonGraphicItem),
graphical_curve |> decode.map(CurveGraphicItem),
dimension |> decode.map(DimensionGraphicItem),
graphical_bounding_box |> decode.map(BoundingBoxGraphicItem),
],
then: next,
)
}
pub type SymbolText {
SymbolText(text: String, position: PositionIdentifier, effects: Effects)
}
pub fn symbol_text(then next: NextFn(SymbolText, a)) -> Decoder(a) {
decode.token(named: "text", then: next, with: {
use text <- decode.string()
use position <- position_identifier()
use effects <- effects()
decode.success(SymbolText(text:, position:, effects:))
})
}
pub type SymbolTextBox {
SymbolTextBox(
text: String,
position: PositionIdentifier,
size: Size,
margins: Option(#(Float, Float, Float, Float)),
stroke: Stroke,
fill: Fill,
effects: Effects,
)
}
pub fn symbol_text_box(then next: NextFn(SymbolTextBox, a)) -> Decoder(a) {
decode.token(named: "text_box", then: next, with: {
use text <- decode.string()
use position <- position_identifier()
use size <- size()
use margins <- decode.optional(margins)
use stroke <- stroke()
use fill <- fill()
use effects <- effects()
decode.success(SymbolTextBox(
text:,
position:,
size:,
margins:,
stroke:,
fill:,
effects:,
))
})
}
pub type SymbolLine {
SymbolLine(points: Points, stroke: Stroke, fill: Fill)
}
pub fn symbol_line(then next: NextFn(SymbolLine, a)) -> Decoder(a) {
decode.token(named: "polyline", then: next, with: {
use points <- points()
use stroke <- stroke()
use fill <- fill()
decode.success(SymbolLine(points:, stroke:, fill:))
})
}
pub type SymbolRectangle {
SymbolRectangle(start: XY, end: XY, stroke: Stroke, fill: Fill)
}
pub fn symbol_rectangle(then next: NextFn(SymbolRectangle, a)) -> Decoder(a) {
decode.token(named: "rectangle", then: next, with: {
use start <- custom_xy("start")
use end <- custom_xy("end")
use stroke <- stroke()
use fill <- fill()
decode.success(SymbolRectangle(start:, end:, stroke:, fill:))
})
}
pub type SymbolCircle {
SymbolCircle(center: XY, radius: Float, stroke: Stroke, fill: Fill)
}
pub fn symbol_circle(then next: NextFn(SymbolCircle, a)) -> Decoder(a) {
decode.token(named: "circle", then: next, with: {
use center <- custom_xy("center")
use radius <- decode.token_wrapper(named: "radius", with: decode.float)
use stroke <- stroke()
use fill <- fill()
decode.success(SymbolCircle(center:, radius:, stroke:, fill:))
})
}
pub type SymbolArc {
SymbolArc(start: XY, mid: XY, end: XY, stroke: Stroke, fill: Fill)
}
pub fn symbol_arc(then next: NextFn(SymbolArc, a)) -> Decoder(a) {
decode.token(named: "arc", then: next, with: {
use start <- custom_xy("start")
use mid <- custom_xy("mid")
use end <- custom_xy("end")
use stroke <- stroke()
use fill <- fill()
decode.success(SymbolArc(start:, mid:, end:, stroke:, fill:))
})
}
pub type SymbolCurve {
SymbolCurve(points: Points, stroke: Stroke, fill: Fill)
}
pub fn symbol_curve(then next: NextFn(SymbolCurve, a)) -> Decoder(a) {
decode.token(named: "bezier", then: next, with: {
use points <- points()
use stroke <- stroke()
use fill <- fill()
decode.success(SymbolCurve(points:, stroke:, fill:))
})
}
pub type PinElectricalType {
InputElectricalType
OutputElectricalType
BidirectionalElectricalType
TriStateElectricalType
PassiveElectricalType
FreeElectricalType
UnspecifiedElectricalType
PowerInElectricalType
PowerOutElectricalType
OpenCollectorElectricalType
OpenEmitterElectricalType
NoConnectElectricalType
}
pub fn pin_electrical_type(
then next: NextFn(PinElectricalType, a),
) -> Decoder(a) {
decode.enum(
with: [
#("input", InputElectricalType),
#("output", OutputElectricalType),
#("bidirectional", BidirectionalElectricalType),
#("tri_state", TriStateElectricalType),
#("passive", PassiveElectricalType),
#("free", FreeElectricalType),
#("unspecified", UnspecifiedElectricalType),
#("power_in", PowerInElectricalType),
#("power_out", PowerOutElectricalType),
#("open_collector", OpenCollectorElectricalType),
#("open_emitter", OpenEmitterElectricalType),
#("no_connect", NoConnectElectricalType),
],
then: next,
)
}
pub type PinGraphicalStyle {
LineGraphicalStyle
InvertedGraphicalStyle
ClockGraphicalStyle
InvertedClockGraphicalStyle
InputLowGraphicalStyle
ClockLowGraphicalStyle
OutputLowGraphicalStyle
EdgeClockHighGraphicalStyle
NonLogicGraphicalStyle
}
pub fn pin_graphical_style(
then next: NextFn(PinGraphicalStyle, a),
) -> Decoder(a) {
decode.enum(
with: [
#("line", LineGraphicalStyle),
#("inverted", InvertedGraphicalStyle),
#("clock", ClockGraphicalStyle),
#("inverted_clock", InvertedClockGraphicalStyle),
#("input_low", InputLowGraphicalStyle),
#("clock_low", ClockLowGraphicalStyle),
#("output_low", OutputLowGraphicalStyle),
#("edge_clock_high", EdgeClockHighGraphicalStyle),
#("non_logic", NonLogicGraphicalStyle),
],
then: next,
)
}
pub type PinName {
PinName(name: String, effects: Effects)
}
pub fn pin_name(then next: NextFn(PinName, a)) -> Decoder(a) {
decode.token(named: "name", then: next, with: {
use name <- decode.string()
use effects <- effects()
decode.success(PinName(name:, effects:))
})
}
pub type PinNumber {
PinNumber(number: String, effects: Effects)
}
pub fn pin_number(then next: NextFn(PinNumber, a)) -> Decoder(a) {
decode.token(named: "number", then: next, with: {
use number <- decode.string()
use effects <- effects()
decode.success(PinNumber(number:, effects:))
})
}
pub type PinAlternate {
PinAlternate(
name: String,
electrical_type: PinElectricalType,
graphical_style: PinGraphicalStyle,
)
}
pub fn pin_alternate(then next: NextFn(PinAlternate, a)) -> Decoder(a) {
decode.token(named: "alternate", then: next, with: {
use name <- decode.string()
use electrical_type <- pin_electrical_type()
use graphical_style <- pin_graphical_style()
decode.success(PinAlternate(name:, electrical_type:, graphical_style:))
})
}
pub type SymbolPin {
SymbolPin(
electrical_type: PinElectricalType,
graphical_style: PinGraphicalStyle,
position: PositionIdentifier,
length: Float,
hide: Option(Bool),
name: PinName,
number: PinNumber,
alternatives: List(PinAlternate),
)
}
pub fn symbol_pin(then next: NextFn(SymbolPin, a)) -> Decoder(a) {
decode.token(named: "pin", then: next, with: {
use electrical_type <- pin_electrical_type()
use graphical_style <- pin_graphical_style()
use position <- position_identifier()
use length <- decode.token_wrapper(named: "length", with: decode.float)
use hide <- decode.optional(hide)
use name <- pin_name()
use number <- pin_number()
use alternatives <- decode.list(pin_alternate)
decode.success(SymbolPin(
electrical_type:,
graphical_style:,
position:,
length:,
hide:,
name:,
number:,
alternatives:,
))
})
}
pub type SymbolGraphicItem {
TextSymbolGraphicItem(SymbolText)
TextBoxSymbolGraphicItem(SymbolTextBox)
LineSymbolGraphicItem(SymbolLine)
RectangleSymbolGraphicItem(SymbolRectangle)
CircleSymbolGraphicItem(SymbolCircle)
ArcSymbolGraphicItem(SymbolArc)
CurveSymbolGraphicItem(SymbolCurve)
}
pub fn symbol_graphic_item(
then next: NextFn(SymbolGraphicItem, a),
) -> Decoder(a) {
decode.one_of(
symbol_text |> decode.map(TextSymbolGraphicItem),
or: [
symbol_text_box |> decode.map(TextBoxSymbolGraphicItem),
symbol_line |> decode.map(LineSymbolGraphicItem),
symbol_rectangle |> decode.map(RectangleSymbolGraphicItem),
symbol_circle |> decode.map(CircleSymbolGraphicItem),
symbol_arc |> decode.map(ArcSymbolGraphicItem),
symbol_curve |> decode.map(CurveSymbolGraphicItem),
],
then: next,
)
}
pub type PadType {
ThroughHolePadType
SmdPadPadType
ConnectPadType
NpThroughHolePadType
}
pub fn pad_type(then next: NextFn(PadType, a)) -> Decoder(a) {
decode.enum(
with: [
#("thru_hole", ThroughHolePadType),
#("smd", SmdPadPadType),
#("connect", ConnectPadType),
#("np_thru_hole", NpThroughHolePadType),
],
then: next,
)
}
pub type PadShape {
CirclePadShape
RectanglePadShape
OvalPadShape
TrapezoidPadShape
RoundRectPadShape
CustomPadShape
}
pub fn pad_shape(then next: NextFn(PadShape, a)) -> Decoder(a) {
decode.enum(
with: [
#("circle", CirclePadShape),
#("rect", RectanglePadShape),
#("oval", OvalPadShape),
#("roundrect", RoundRectPadShape),
#("trapezoid", TrapezoidPadShape),
#("custom", CustomPadShape),
],
then: next,
)
}
pub type PadDrillDefinition {
PadDrillDefinition(
oval: Bool,
diameter: Option(Float),
width: Option(Float),
offset: Option(XY),
)
}
pub fn pad_drill_definition(
then next: NextFn(PadDrillDefinition, a),
) -> Decoder(a) {
decode.token(named: "drill", then: next, with: {
use oval <- decode.flag("oval")
use diameter <- decode.optional(decode.float)
use width <- decode.optional(decode.float)
use offset <- decode.optional(custom_xy("offset", then: _))
decode.success(PadDrillDefinition(oval:, diameter:, width:, offset:))
})
}
pub type PadProperty {
BgaPadProperty
FiducialGlobPadProperty
FiducialLocPadProperty
TestpointPadProperty
HeatsinkPadProperty
CastellatedPadProperty
}
pub fn pad_property(then next: NextFn(PadProperty, a)) -> Decoder(a) {
decode.enum(
with: [
#("pad_prop_bga", BgaPadProperty),
#("pad_prop_fiducial_glob", FiducialGlobPadProperty),
#("pad_prop_fiducial_loc", FiducialLocPadProperty),
#("pad_prop_testpoint", TestpointPadProperty),
#("pad_prop_heatsink", HeatsinkPadProperty),
#("pad_prop_castellated", CastellatedPadProperty),
],
then: next,
)
}
pub type Corner {
TopLeft
TopRight
BottomLeft
BottomRight
}
pub fn corner(then next: NextFn(Corner, a)) -> Decoder(a) {
decode.enum(
with: [
#("top_left", TopLeft),
#("top_right", TopRight),
#("bottom_left", BottomLeft),
#("bottom_right", BottomRight),
],
then: next,
)
}
pub type Net {
Net(number: Int, name: String)
}
pub fn net(then next: NextFn(Net, a)) -> Decoder(a) {
decode.token(named: "net", then: next, with: {
use number <- decode.int()
use name <- decode.string()
decode.success(Net(number:, name:))
})
}
pub type ClearanceType {
OutlineClearanceType
ConvexHullClearanceType
}
pub fn clearance_type(then next: NextFn(ClearanceType, a)) -> Decoder(a) {
decode.enum(
with: [
#("outline", OutlineClearanceType),
#("convexhull", ConvexHullClearanceType),
],
then: next,
)
}
pub type AnchorPadShape {
RectangleAnchorPadShape
CircleAnchorPadShape
}
pub fn anchor_pad_shape(then next: NextFn(AnchorPadShape, a)) -> Decoder(a) {
decode.enum(
with: [
#("rect", RectangleAnchorPadShape),
#("circle", CircleAnchorPadShape),
],
then: next,
)
}
pub type CustomPadOptions {
CustomPadOptions(clearance: ClearanceType, anchor: AnchorPadShape)
}
pub fn custom_pad_options(then next: NextFn(CustomPadOptions, a)) -> Decoder(a) {
decode.token(named: "options", then: next, with: {
use clearance <- decode.token_wrapper(
named: "clearance",
with: clearance_type,
)
use anchor <- decode.token_wrapper(named: "anchor", with: anchor_pad_shape)
decode.success(CustomPadOptions(clearance:, anchor:))
})
}
pub type CustomPadPrimitives {
CustomPadPrimitives(
graphic_items: List(GraphicItem),
width: Option(Float),
fill: Option(Bool),
)
}
pub fn custom_pad_primitives(
then next: NextFn(CustomPadPrimitives, a),
) -> Decoder(a) {
decode.token(named: "primitives", then: next, with: {
use graphic_items <- decode.list(graphic_item)
use width <- decode.optional(width)
use fill <- decode.optional(filled)
decode.success(CustomPadPrimitives(graphic_items:, width:, fill:))
})
}
pub type Pad {
Pad(
number: String,
type_: PadType,
shape: PadShape,
position: PositionIdentifier,
locked: Bool,
size: Size,
drill: Option(PadDrillDefinition),
rect_delta: Option(XY),
property: Option(PadProperty),
layers: List(Layer),
remove_unused_layers: Option(Bool),
keep_end_layers: Option(Bool),
roundrect_rratio: Option(Float),
chamfer_ratio: Option(Float),
chamfer: Option(List(Corner)),
net: Option(Net),
pin_function: Option(String),
pin_type: Option(String),
die_length: Option(Float),
solder_mask_margin: Option(Float),
solder_paste_margin: Option(Float),
solder_paste_margin_ratio: Option(Float),
clearance: Option(Float),
zone_connection: Option(ConnectionType),
thermal_width: Option(Float),
thermal_gap: Option(Float),
thermal_bridge_width: Option(Float),
thermal_bridge_angle: Option(Float),
custom_options: Option(CustomPadOptions),
custom_primitives: Option(CustomPadPrimitives),
uuid: Option(Uuid),
timestamp: Option(Timestamp),
)
}
pub fn pad(then next: NextFn(Pad, a)) -> Decoder(a) {
decode.token(named: "pad", then: next, with: {
use number <- decode.name_number_string()
use type_ <- pad_type()
use shape <- pad_shape()
use position <- position_identifier()
use locked <- decode.flag("locked")
use size <- size()
use drill <- decode.optional(pad_drill_definition)
use rect_delta <- decode.optional(custom_xy(named: "rect_delta", then: _))
use property <- decode.optional(decode.token_wrapper(
named: "property",
with: pad_property,
then: _,
))
use layers <- layers()
use remove_unused_layers <- decode.optional(decode.token_wrapper(
named: "remove_unused_layers",
with: decode.optional(yes_no, then: _),
then: _,
))
let remove_unused_layers = option.flatten(remove_unused_layers)
use keep_end_layers <- decode.optional(decode.token_wrapper(
named: "keep_end_layers",
with: decode.optional(yes_no, then: _),
then: _,
))
let keep_end_layers = option.flatten(keep_end_layers)
use roundrect_rratio <- decode.optional(decode.token_wrapper(
named: "roundrect_rratio",
with: decode.float,
then: _,
))
use chamfer_ratio <- decode.optional(decode.token_wrapper(
named: "chamfer_ratio",
with: decode.float,
then: _,
))
use chamfer <- decode.optional(decode.token_wrapper(
named: "chamfer",
with: decode.list(corner, then: _),
then: _,
))
use net <- decode.optional(net)
use pin_function <- decode.optional(decode.token_wrapper(
named: "pinfunction",
with: decode.string,
then: _,
))
use pin_type <- decode.optional(decode.token_wrapper(
named: "pintype",
with: decode.string,
then: _,
))
use die_length <- decode.optional(decode.token_wrapper(
named: "die_length",
with: decode.float,
then: _,
))
use solder_mask_margin <- decode.optional(decode.token_wrapper(
named: "solder_mask_margin",
with: decode.float,
then: _,
))
use solder_paste_margin <- decode.optional(decode.token_wrapper(
named: "solder_paste_margin",
with: decode.float,
then: _,
))
use solder_paste_margin_ratio <- decode.optional(decode.token_wrapper(
named: "solder_paste_margin_ratio",
with: decode.float,
then: _,
))
use clearance <- decode.optional(decode.token_wrapper(
named: "clearance",
with: decode.float,
then: _,
))
use zone_connection <- decode.optional(decode.token_wrapper(
named: "zone_connect",
with: connection_type,
then: _,
))
use thermal_width <- decode.optional(decode.token_wrapper(
named: "thermal_width",
with: decode.float,
then: _,
))
use thermal_gap <- decode.optional(decode.token_wrapper(
named: "thermal_gap",
with: decode.float,
then: _,
))
use thermal_bridge_width <- decode.optional(decode.token_wrapper(
named: "thermal_bridge_width",
with: decode.float,
then: _,
))
use thermal_bridge_angle <- decode.optional(decode.token_wrapper(
named: "thermal_bridge_angle",
with: decode.float,
then: _,
))
use custom_options <- decode.optional(custom_pad_options)
use custom_primitives <- decode.optional(custom_pad_primitives)
use uuid <- decode.optional(uuid)
use timestamp <- decode.optional(timestamp)
decode.success(Pad(
number:,
type_:,
shape:,
position:,
locked:,
size:,
drill:,
rect_delta:,
property:,
layers:,
remove_unused_layers:,
keep_end_layers:,
roundrect_rratio:,
chamfer_ratio:,
chamfer:,
net:,
pin_function:,
pin_type:,
die_length:,
solder_mask_margin:,
solder_paste_margin:,
solder_paste_margin_ratio:,
clearance:,
zone_connection:,
thermal_width:,
thermal_gap:,
thermal_bridge_width:,
thermal_bridge_angle:,
custom_options:,
custom_primitives:,
uuid:,
timestamp:,
))
})
}
pub type HatchStyle {
NoHatch
EdgeHatchStyle
FullHatchStyle
}
pub fn hatch_style(then next: NextFn(HatchStyle, a)) -> Decoder(a) {
decode.enum(
with: [
#("none", NoHatch),
#("edge", EdgeHatchStyle),
#("full", FullHatchStyle),
],
then: next,
)
}
pub type Hatch {
Hatch(style: HatchStyle, pitch: Float)
}
pub fn hatch(then next: NextFn(Hatch, a)) -> Decoder(a) {
decode.token(named: "hatch", then: next, with: {
use style <- hatch_style()
use pitch <- decode.float()
decode.success(Hatch(style:, pitch:))
})
}
pub type ConnectPads {
ConnectPads(connection_type: Option(ConnectionType), clearance: Float)
}
pub fn connect_pads(then next: NextFn(ConnectPads, a)) -> Decoder(a) {
decode.token(named: "connect_pads", then: next, with: {
use connection_type <- decode.optional(connection_type)
use clearance <- decode.token_wrapper(
named: "clearance",
with: decode.float,
)
decode.success(ConnectPads(connection_type:, clearance:))
})
}
pub type ZoneKeepoutSettings {
ZoneKeepoutSettings(
tracks: Bool,
vias: Bool,
pads: Bool,
copper_pour: Bool,
footprints: Bool,
)
}
pub fn zone_keepout_settings(
then next: NextFn(ZoneKeepoutSettings, a),
) -> Decoder(a) {
decode.token(named: "keepout", then: next, with: {
use tracks <- decode.token_wrapper(named: "tracks", with: allowed)
use vias <- decode.token_wrapper(named: "vias", with: allowed)
use pads <- decode.token_wrapper(named: "pads", with: allowed)
use copper_pour <- decode.token_wrapper(named: "copperpour", with: allowed)
use footprints <- decode.token_wrapper(named: "footprints", with: allowed)
decode.success(ZoneKeepoutSettings(
tracks:,
vias:,
pads:,
copper_pour:,
footprints:,
))
})
}
pub type FillMode {
HatchedFillMode
}
pub fn fill_mode(then next: NextFn(FillMode, a)) -> Decoder(a) {
decode.enum(with: [#("hatched", HatchedFillMode)], then: next)
}
pub type SmoothingStyle {
ChamferSmoothingStyle
FilletSmoothingStyle
}
pub fn smoothing_style(then next: NextFn(SmoothingStyle, a)) -> Decoder(a) {
decode.enum(
with: [
#("chamfer", ChamferSmoothingStyle),
#("fillet", FilletSmoothingStyle),
],
then: next,
)
}
pub type IslandRemovalMode {
AlwaysRemove
NeverRemove
MinimumArea
}
pub fn island_removal_mode(
then next: NextFn(IslandRemovalMode, a),
) -> Decoder(a) {
decode.int_enum(with: [AlwaysRemove, NeverRemove, MinimumArea], then: next)
}
pub type SmoothingLevel {
NoSmoothingLevel
FilletSmoothingLevel
ArcMinimumSmoothingLevel
ArcMaximumSmoothingLevel
}
pub fn smoothing_level(then next: NextFn(SmoothingLevel, a)) -> Decoder(a) {
decode.int_enum(
with: [
NoSmoothingLevel,
FilletSmoothingLevel,
ArcMinimumSmoothingLevel,
ArcMaximumSmoothingLevel,
],
then: next,
)
}
pub type BorderAlgorithm {
ZoneMinimumThicknessBorderAlgorithm
HatchThicknessBorderAlgorithm
}
pub fn border_algorithm(then next: NextFn(BorderAlgorithm, a)) -> Decoder(a) {
decode.int_enum(
with: [ZoneMinimumThicknessBorderAlgorithm, HatchThicknessBorderAlgorithm],
then: next,
)
}
pub type ZoneFillSettings {
ZoneFillSettings(
filled: Bool,
mode: Option(FillMode),
thermal_gap: Option(Float),
thermal_bridge_width: Option(Float),
smoothing: Option(SmoothingStyle),
radius: Option(Float),
island_removal_mode: Option(IslandRemovalMode),
island_area_min: Option(Float),
hatch_thickness: Option(Float),
hatch_gap: Option(Float),
hatch_orientation: Option(Float),
hatch_smoothing_level: Option(SmoothingLevel),
hatch_smoothing_value: Option(Float),
hatch_border_algorithm: Option(BorderAlgorithm),
hatch_min_hole_area: Option(Float),
)
}
pub fn zone_fill_settings(then next: NextFn(ZoneFillSettings, a)) -> Decoder(a) {
decode.token(named: "fill", then: next, with: {
use filled <- decode.flag("yes")
use mode <- decode.optional(decode.token_wrapper(
named: "mode",
with: fill_mode,
then: _,
))
use thermal_gap <- decode.optional(decode.token_wrapper(
named: "thermal_gap",
with: decode.float,
then: _,
))
use thermal_bridge_width <- decode.optional(decode.token_wrapper(
named: "thermal_bridge_width",
with: decode.float,
then: _,
))
use smoothing <- decode.optional(decode.token_wrapper(
named: "smoothing",
with: smoothing_style,
then: _,
))
use radius <- decode.optional(decode.token_wrapper(
named: "radius",
with: decode.float,
then: _,
))
use island_removal_mode <- decode.optional(decode.token_wrapper(
named: "island_removal_mode",
with: island_removal_mode,
then: _,
))
use island_area_min <- decode.optional(decode.token_wrapper(
named: "island_area_min",
with: decode.float,
then: _,
))
use hatch_thickness <- decode.optional(decode.token_wrapper(
named: "hatch_thickness",
with: decode.float,
then: _,
))
use hatch_gap <- decode.optional(decode.token_wrapper(
named: "hatch_gap",
with: decode.float,
then: _,
))
use hatch_orientation <- decode.optional(decode.token_wrapper(
named: "hatch_orientation",
with: decode.float,
then: _,
))
use hatch_smoothing_level <- decode.optional(decode.token_wrapper(
named: "hatch_smoothing_level",
with: smoothing_level,
then: _,
))
use hatch_smoothing_value <- decode.optional(decode.token_wrapper(
named: "hatch_smoothing_value",
with: decode.float,
then: _,
))
use hatch_border_algorithm <- decode.optional(decode.token_wrapper(
named: "hatch_border_algorithm",
with: border_algorithm,
then: _,
))
use hatch_min_hole_area <- decode.optional(decode.token_wrapper(
named: "hatch_min_hole_area",
with: decode.float,
then: _,
))
decode.success(ZoneFillSettings(
filled:,
mode:,
thermal_gap:,
thermal_bridge_width:,
smoothing:,
radius:,
island_removal_mode:,
island_area_min:,
hatch_thickness:,
hatch_gap:,
hatch_orientation:,
hatch_smoothing_level:,
hatch_smoothing_value:,
hatch_border_algorithm:,
hatch_min_hole_area:,
))
})
}
pub type FilledPolygon {
FilledPolygon(layer: Layer, points: Points)
}
pub fn filled_polygon(then next: NextFn(FilledPolygon, a)) -> Decoder(a) {
decode.token(named: "filled_polygon", then: next, with: {
use layer <- layer()
use points <- points()
decode.success(FilledPolygon(layer:, points:))
})
}
pub type FillSegments {
FillSegments(layer: Layer, points: Points)
}
pub fn fill_segments(then next: NextFn(FillSegments, a)) -> Decoder(a) {
decode.token(named: "fill_segments", then: next, with: {
use layer <- layer()
use points <- points()
decode.success(FillSegments(layer:, points:))
})
}
pub type ZonePlacement {
ZonePlacement(enabled: Bool, sheet_name: String)
}
pub fn zone_placement(then next: NextFn(ZonePlacement, a)) -> Decoder(a) {
decode.token(named: "placement", then: next, with: {
use enabled <- decode.token_wrapper(named: "enabled", with: yes_no, then: _)
use sheet_name <-
decode.token_wrapper(named: "sheetname", with: decode.string, then: _)
decode.success(ZonePlacement(enabled:, sheet_name:))
})
}
pub type Zone {
Zone(
net: Int,
net_name: String,
layers: List(Layer),
uuid: Option(Uuid),
timestamp: Option(Timestamp),
name: Option(String),
hatch: Hatch,
priority: Option(Int),
connect_pads: ConnectPads,
min_thickness: Float,
filled_areas_thickness: Option(Bool),
keepout_settings: Option(ZoneKeepoutSettings),
placement: Option(ZonePlacement),
fill_settings: ZoneFillSettings,
polygon: PolyPoints,
fill_polygons: List(FilledPolygon),
fill_segments: List(FillSegments),
)
}
pub fn zone(then next: NextFn(Zone, a)) -> Decoder(a) {
decode.token(named: "zone", then: next, with: {
use net <- decode.token_wrapper(named: "net", with: decode.int)
use net_name <- decode.token_wrapper(named: "net_name", with: decode.string)
use layers <- decode.one_of(layer |> decode.map(list.wrap), or: [layers])
use uuid <- decode.optional(uuid)
use timestamp <- decode.optional(timestamp)
use name <- decode.optional(decode.token_wrapper(
named: "name",
with: decode.string,
then: _,
))
use hatch <- hatch()
use priority <- decode.optional(decode.token_wrapper(
named: "priority",
with: decode.int,
then: _,
))
use connect_pads <- connect_pads()
use min_thickness <- decode.token_wrapper(
named: "min_thickness",
with: decode.float,
)
use filled_areas_thickness <- decode.optional(decode.token_wrapper(
named: "filled_areas_thickness",
with: yes_no,
then: _,
))
use keepout_settings <- decode.optional(zone_keepout_settings)
use placement <- decode.optional(zone_placement)
use fill_settings <- zone_fill_settings()
use polygon <- decode.token_wrapper(named: "polygon", with: poly_points)
use fill_polygons <- decode.list(filled_polygon)
use fill_segments <- decode.list(fill_segments)
decode.success(Zone(
net:,
net_name:,
layers:,
uuid:,
timestamp:,
name:,
hatch:,
priority:,
connect_pads:,
min_thickness:,
filled_areas_thickness:,
keepout_settings:,
placement:,
fill_settings:,
polygon:,
fill_polygons:,
fill_segments:,
))
})
}
pub type Group {
Group(name: String, uuid: Uuid, members: List(Uuid))
}
pub fn group(then next: NextFn(Group, a)) -> Decoder(a) {
decode.token(named: "group", then: next, with: {
use name <- decode.string()
use uuid <- uuid()
use members <- decode.token_wrapper(named: "members", with: decode.list(
decode.string,
then: _,
))
let members = list.map(members, Uuid)
decode.success(Group(name:, uuid:, members:))
})
}
pub type FootprintModel {
FootprintModel(
file: String,
hide: Option(Bool),
offset: XYZ,
scale: XYZ,
rotate: XYZ,
)
}
pub fn footprint_model(then next: NextFn(FootprintModel, a)) -> Decoder(a) {
decode.token(named: "model", then: next, with: {
use file <- decode.string()
use hide <- decode.optional(hide)
use offset <- decode.one_of(
decode.token_wrapper(named: "offset", with: xyz, then: _),
or: [decode.token_wrapper(named: "at", with: xyz, then: _)],
)
use scale <- decode.token_wrapper(named: "scale", with: xyz)
use rotate <- decode.token_wrapper(named: "rotate", with: xyz)
decode.success(FootprintModel(file:, hide:, offset:, scale:, rotate:))
})
}
pub type Footprint {
Footprint(
library_link: Option(String),
locked: Bool,
placed: Bool,
layer: Layer,
tedit: Option(String),
uuid: Option(Uuid),
position: Option(PositionIdentifier),
description: Option(String),
tags: Option(String),
properties: List(FootprintProperty),
path: Option(String),
autoplace_cost_90: Option(Int),
autoplace_cost_180: Option(Int),
solder_mask_margin: Option(Float),
solder_paste_ratio: Option(Float),
solder_paste_margin: Option(Float),
solder_paste_margin_ratio: Option(Float),
clearance: Option(Float),
zone_connect: Option(ConnectionType),
thermal_width: Option(Float),
thermal_gap: Option(Float),
attributes: Option(FootprintAttributes),
private_layers: Option(List(String)),
net_tie_pad_groups: Option(List(String)),
graphic_items: List(FootprintGraphicItem),
pads: List(Pad),
zones: List(Zone),
groups: List(Group),
embedded_fonts: Option(Bool),
models: List(FootprintModel),
)
}
fn base_footprint(then next: NextFn(Footprint, a)) -> Decoder(a) {
decode.of(then: next, with: {
use library_link <- decode.optional(decode.string)
use locked <- decode.flag("locked")
use placed <- decode.flag("placed")
use layer <- layer()
use tedit <- decode.optional(decode.token_wrapper(
named: "tedit",
with: decode.name_number_string,
then: _,
))
use uuid <- decode.optional(uuid)
use position <- decode.optional(position_identifier)
use description <- decode.optional(decode.token_wrapper(
named: "descr",
with: decode.string,
then: _,
))
use tags <- decode.optional(decode.token_wrapper(
named: "tags",
with: decode.string,
then: _,
))
use properties_a <- decode.list(footprint_property)
use path <- decode.optional(decode.token_wrapper(
named: "path",
with: decode.string,
then: _,
))
use attributes_a <- decode.optional(footprint_attributes)
use autoplace_cost_90 <- decode.optional(decode.token_wrapper(
named: "autoplace_cost90",
with: decode.int,
then: _,
))
use autoplace_cost_180 <- decode.optional(decode.token_wrapper(
named: "autoplace_cost180",
with: decode.int,
then: _,
))
use solder_mask_margin <- decode.optional(decode.token_wrapper(
named: "solder_mask_margin",
with: decode.float,
then: _,
))
use solder_paste_ratio <- decode.optional(decode.token_wrapper(
named: "solder_paste_ratio",
with: decode.float,
then: _,
))
use solder_paste_margin <- decode.optional(decode.token_wrapper(
named: "solder_paste_margin",
with: decode.float,
then: _,
))
use solder_paste_margin_ratio <- decode.optional(decode.token_wrapper(
named: "solder_paste_margin_ratio",
with: decode.float,
then: _,
))
use properties_b <- decode.list(footprint_property)
let properties = list.append(properties_a, properties_b)
use clearance <- decode.optional(decode.token_wrapper(
named: "clearance",
with: decode.float,
then: _,
))
use zone_connect <- decode.optional(decode.token_wrapper(
named: "zone_connect",
with: connection_type,
then: _,
))
use thermal_width <- decode.optional(decode.token_wrapper(
named: "thermal_width",
with: decode.float,
then: _,
))
use thermal_gap <- decode.optional(decode.token_wrapper(
named: "thermal_gap",
with: decode.float,
then: _,
))
use attributes_b <- decode.optional(footprint_attributes)
let attributes = attributes_a |> option.or(attributes_b)
use private_layers <- decode.optional(decode.token_wrapper(
named: "private_layers",
with: decode.list(decode.string, then: _),
then: _,
))
use net_tie_pad_groups <- decode.optional(decode.token_wrapper(
named: "net_tie_pad_groups",
with: decode.list(decode.string, then: _),
then: _,
))
use graphic_items_a <- decode.list(footprint_graphic_item)
use pads <- decode.list(pad)
use graphic_items_b <- decode.list(footprint_graphic_item)
let graphic_items = list.append(graphic_items_a, graphic_items_b)
use zones <- decode.list(zone)
use groups <- decode.list(group)
use embedded_fonts <- decode.optional(decode.token_wrapper(
named: "embedded_fonts",
with: yes_no,
then: _,
))
use models <- decode.list(footprint_model)
decode.success(Footprint(
library_link:,
locked:,
placed:,
layer:,
tedit:,
uuid:,
position:,
description:,
tags:,
properties:,
path:,
autoplace_cost_90:,
autoplace_cost_180:,
solder_mask_margin:,
solder_paste_ratio:,
solder_paste_margin:,
solder_paste_margin_ratio:,
clearance:,
zone_connect:,
thermal_width:,
thermal_gap:,
attributes:,
private_layers:,
net_tie_pad_groups:,
graphic_items:,
pads:,
zones:,
groups:,
embedded_fonts:,
models:,
))
})
}
pub fn footprint(then next: NextFn(Footprint, a)) -> Decoder(a) {
decode.token_wrapper(named: "footprint", with: base_footprint, then: next)
}
pub type FootprintFile {
FootprintFile(
name: String,
version: Option(Int),
generator: Option(String),
generator_version: Option(String),
footprint: Footprint,
)
}
pub fn footprint_file(then next: NextFn(FootprintFile, a)) -> Decoder(a) {
decode.one_of(
decode.token(
named: "footprint",
with: {
use name <- decode.string()
use version <- decode.token_wrapper(named: "version", with: decode.int)
let version = Some(version)
use generator <- decode.token_wrapper(
named: "generator",
with: decode.name_string,
)
let generator = Some(generator)
use generator_version <- decode.optional(decode.token_wrapper(
named: "generator_version",
with: decode.string,
then: _,
))
use footprint <- base_footprint()
decode.success(FootprintFile(
name:,
version:,
generator:,
generator_version:,
footprint:,
))
},
then: _,
),
or: [
decode.token(
named: "module",
with: {
use name <- decode.name_string()
let version = None
let generator = None
let generator_version = None
use footprint <- base_footprint()
decode.success(FootprintFile(
name:,
version:,
generator:,
generator_version:,
footprint:,
))
},
then: _,
),
],
then: next,
)
}
pub type SymbolProperty {
SymbolProperty(
key: String,
value: String,
id: Option(Int),
position: PositionIdentifier,
show_name: Bool,
effects: Effects,
)
}
pub fn symbol_property(then next: NextFn(SymbolProperty, a)) -> Decoder(a) {
decode.token(named: "property", then: next, with: {
use key <- decode.string()
use value <- decode.string()
use id <- decode.optional(decode.token_wrapper(
named: "id",
with: decode.int,
then: _,
))
use position <- position_identifier()
use show_name <- decode.optional(decode.token(
named: "show_name",
with: decode.success(Nil),
then: _,
))
let show_name = option.is_some(show_name)
use effects <- effects()
decode.success(SymbolProperty(
key:,
value:,
id:,
position:,
show_name:,
effects:,
))
})
}
pub type Symbol {
Symbol(
library_unit_id: String,
extends: Option(String),
power: Bool,
hide_pin_numbers: Option(Bool),
hide_pin_names: Option(Bool),
pin_names_offset: Option(Float),
exclude_from_sim: Option(Bool),
in_bom: Option(Bool),
on_board: Option(Bool),
properties: List(SymbolProperty),
graphics_items: List(SymbolGraphicItem),
pins: List(SymbolPin),
units: List(Symbol),
unit_name: Option(String),
embedded_fonts: Option(Bool),
)
}
fn base_symbol(then next: NextFn(Symbol, a)) -> Decoder(a) {
decode.of(then: next, with: {
use library_unit_id <- decode.string()
use extends <- decode.optional(decode.token_wrapper(
named: "extends",
with: decode.string,
then: _,
))
use power <- decode.optional(decode.token(
named: "power",
with: decode.success(Nil),
then: _,
))
let power = option.is_some(power)
use hide_pin_numbers <- decode.optional(decode.token_wrapper(
named: "pin_numbers",
with: decode.optional(hide, then: _),
then: _,
))
let hide_pin_numbers = option.flatten(hide_pin_numbers)
use pin_names <- decode.optional(decode.token(
named: "pin_names",
with: {
use offset <- decode.optional(decode.token_wrapper(
named: "offset",
with: decode.float,
then: _,
))
use hide <- decode.optional(hide)
decode.success(#(offset, hide))
},
then: _,
))
let hide_pin_names = option.map(pin_names, pair.second) |> option.flatten
let pin_names_offset = option.then(pin_names, pair.first)
use exclude_from_sim <- decode.optional(decode.token_wrapper(
named: "exclude_from_sim",
with: yes_no,
then: _,
))
use in_bom <- decode.optional(decode.token_wrapper(
named: "in_bom",
with: yes_no,
then: _,
))
use on_board <- decode.optional(decode.token_wrapper(
named: "on_board",
with: yes_no,
then: _,
))
use properties <- decode.list(symbol_property)
use graphics_items <- decode.list(symbol_graphic_item)
use pins <- decode.list(symbol_pin)
use units <- decode.list(symbol)
use unit_name <- decode.optional(decode.token_wrapper(
named: "unit_name",
with: decode.string,
then: _,
))
use embedded_fonts <- decode.optional(decode.token_wrapper(
named: "embedded_fonts",
with: yes_no,
then: _,
))
decode.success(Symbol(
library_unit_id:,
extends:,
power:,
hide_pin_numbers:,
hide_pin_names:,
pin_names_offset:,
exclude_from_sim:,
in_bom:,
on_board:,
properties:,
graphics_items:,
pins:,
units:,
unit_name:,
embedded_fonts:,
))
})
}
pub fn symbol(then next: NextFn(Symbol, a)) -> Decoder(a) {
decode.token_wrapper(named: "symbol", with: base_symbol, then: next)
}
pub type SymbolLibrary {
SymbolLibrary(
version: Int,
generator: String,
generator_version: Option(String),
symbols: List(Symbol),
)
}
pub fn symbol_library(then next: NextFn(SymbolLibrary, a)) -> Decoder(a) {
decode.token(named: "kicad_symbol_lib", then: next, with: {
use version <- decode.token_wrapper(named: "version", with: decode.int)
use generator <- decode.token_wrapper(
named: "generator",
with: decode.name_string,
)
use generator_version <- decode.optional(decode.token_wrapper(
named: "generator_version",
with: decode.string,
then: _,
))
use symbols <- decode.list(symbol)
decode.success(SymbolLibrary(
version:,
generator:,
generator_version:,
symbols:,
))
})
}