3065 lines
77 KiB
Gleam
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(height: Float, width: Float)
|
|
}
|
|
|
|
pub fn size(then next: NextFn(Size, a)) -> Decoder(a) {
|
|
decode.token(named: "size", then: next, with: {
|
|
use height <- decode.float()
|
|
use width <- decode.float()
|
|
decode.success(Size(height:, width:))
|
|
})
|
|
}
|
|
|
|
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:,
|
|
))
|
|
})
|
|
}
|