Fix remaining legacy parsing issues
This commit is contained in:
parent
421924a339
commit
6029c4ea67
3 changed files with 269 additions and 154 deletions
|
@ -1,3 +1,4 @@
|
|||
import gleam/bit_array
|
||||
import gleam/float
|
||||
import gleam/int
|
||||
import gleam/list
|
||||
|
@ -187,7 +188,10 @@ fn do_string(source: BitArray, acc: List(UtfCodepoint)) -> Parsed(String) {
|
|||
<<92, 114, rest:bits>> -> do_string(rest, [utf_codepoint_unsafe(13), ..acc])
|
||||
<<92, cp:utf8_codepoint, rest:bits>> -> do_string(rest, [cp, ..acc])
|
||||
<<cp:utf8_codepoint, rest:bits>> -> do_string(rest, [cp, ..acc])
|
||||
source -> Error(InvalidUtf8Character(source))
|
||||
source ->
|
||||
Error(InvalidUtf8Character(
|
||||
source |> bit_array.slice(0, 4) |> result.unwrap(source),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,6 +199,7 @@ type ParsedType {
|
|||
ParsedInt
|
||||
ParsedFloat
|
||||
ParsedName
|
||||
ParsedString
|
||||
}
|
||||
|
||||
fn do_name_number(
|
||||
|
@ -207,7 +212,7 @@ fn do_name_number(
|
|||
rest,
|
||||
#([utf_codepoint_unsafe(i), ..cps], case cps {
|
||||
[] -> parsed_type
|
||||
_ -> ParsedName
|
||||
_ -> ParsedString
|
||||
}),
|
||||
)
|
||||
<<46 as i, rest:bits>>, #(cps, parsed_type) ->
|
||||
|
@ -215,7 +220,7 @@ fn do_name_number(
|
|||
rest,
|
||||
#([utf_codepoint_unsafe(i), ..cps], case parsed_type {
|
||||
ParsedInt -> ParsedFloat
|
||||
_ -> ParsedName
|
||||
_ -> ParsedString
|
||||
}),
|
||||
)
|
||||
<<48 as i, rest:bits>>, #(cps, parsed_type)
|
||||
|
@ -229,62 +234,77 @@ fn do_name_number(
|
|||
| <<56 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<57 as i, rest:bits>>, #(cps, parsed_type)
|
||||
-> do_name_number(rest, #([utf_codepoint_unsafe(i), ..cps], parsed_type))
|
||||
<<65 as i, rest:bits>>, #(cps, _)
|
||||
| <<66 as i, rest:bits>>, #(cps, _)
|
||||
| <<67 as i, rest:bits>>, #(cps, _)
|
||||
| <<68 as i, rest:bits>>, #(cps, _)
|
||||
| <<69 as i, rest:bits>>, #(cps, _)
|
||||
| <<70 as i, rest:bits>>, #(cps, _)
|
||||
| <<71 as i, rest:bits>>, #(cps, _)
|
||||
| <<72 as i, rest:bits>>, #(cps, _)
|
||||
| <<73 as i, rest:bits>>, #(cps, _)
|
||||
| <<74 as i, rest:bits>>, #(cps, _)
|
||||
| <<75 as i, rest:bits>>, #(cps, _)
|
||||
| <<76 as i, rest:bits>>, #(cps, _)
|
||||
| <<77 as i, rest:bits>>, #(cps, _)
|
||||
| <<78 as i, rest:bits>>, #(cps, _)
|
||||
| <<79 as i, rest:bits>>, #(cps, _)
|
||||
| <<80 as i, rest:bits>>, #(cps, _)
|
||||
| <<81 as i, rest:bits>>, #(cps, _)
|
||||
| <<82 as i, rest:bits>>, #(cps, _)
|
||||
| <<83 as i, rest:bits>>, #(cps, _)
|
||||
| <<84 as i, rest:bits>>, #(cps, _)
|
||||
| <<85 as i, rest:bits>>, #(cps, _)
|
||||
| <<86 as i, rest:bits>>, #(cps, _)
|
||||
| <<87 as i, rest:bits>>, #(cps, _)
|
||||
| <<88 as i, rest:bits>>, #(cps, _)
|
||||
| <<89 as i, rest:bits>>, #(cps, _)
|
||||
| <<90 as i, rest:bits>>, #(cps, _)
|
||||
| <<97 as i, rest:bits>>, #(cps, _)
|
||||
| <<98 as i, rest:bits>>, #(cps, _)
|
||||
| <<99 as i, rest:bits>>, #(cps, _)
|
||||
| <<100 as i, rest:bits>>, #(cps, _)
|
||||
| <<101 as i, rest:bits>>, #(cps, _)
|
||||
| <<102 as i, rest:bits>>, #(cps, _)
|
||||
| <<103 as i, rest:bits>>, #(cps, _)
|
||||
| <<104 as i, rest:bits>>, #(cps, _)
|
||||
| <<105 as i, rest:bits>>, #(cps, _)
|
||||
| <<106 as i, rest:bits>>, #(cps, _)
|
||||
| <<107 as i, rest:bits>>, #(cps, _)
|
||||
| <<108 as i, rest:bits>>, #(cps, _)
|
||||
| <<109 as i, rest:bits>>, #(cps, _)
|
||||
| <<110 as i, rest:bits>>, #(cps, _)
|
||||
| <<111 as i, rest:bits>>, #(cps, _)
|
||||
| <<112 as i, rest:bits>>, #(cps, _)
|
||||
| <<113 as i, rest:bits>>, #(cps, _)
|
||||
| <<114 as i, rest:bits>>, #(cps, _)
|
||||
| <<115 as i, rest:bits>>, #(cps, _)
|
||||
| <<116 as i, rest:bits>>, #(cps, _)
|
||||
| <<117 as i, rest:bits>>, #(cps, _)
|
||||
| <<118 as i, rest:bits>>, #(cps, _)
|
||||
| <<119 as i, rest:bits>>, #(cps, _)
|
||||
| <<120 as i, rest:bits>>, #(cps, _)
|
||||
| <<121 as i, rest:bits>>, #(cps, _)
|
||||
| <<122 as i, rest:bits>>, #(cps, _)
|
||||
| <<95 as i, rest:bits>>, #(cps, _)
|
||||
| <<42 as i, rest:bits>>, #(cps, _)
|
||||
-> do_name_number(rest, #([utf_codepoint_unsafe(i), ..cps], ParsedName))
|
||||
source, #(cps, parsed_type) -> {
|
||||
<<65 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<66 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<67 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<68 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<69 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<70 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<71 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<72 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<73 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<74 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<75 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<76 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<77 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<78 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<79 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<80 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<81 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<82 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<83 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<84 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<85 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<86 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<87 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<88 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<89 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<90 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<97 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<98 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<99 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<100 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<101 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<102 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<103 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<104 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<105 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<106 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<107 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<108 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<109 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<110 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<111 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<112 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<113 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<114 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<115 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<116 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<117 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<118 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<119 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<120 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<121 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<122 as i, rest:bits>>, #(cps, parsed_type)
|
||||
| <<95 as i, rest:bits>>, #(cps, parsed_type)
|
||||
->
|
||||
do_name_number(
|
||||
rest,
|
||||
#([utf_codepoint_unsafe(i), ..cps], case parsed_type {
|
||||
ParsedInt | ParsedFloat -> ParsedName
|
||||
x -> x
|
||||
}),
|
||||
)
|
||||
<<32, source:bits>>, #(cps, parsed_type)
|
||||
| <<9, source:bits>>, #(cps, parsed_type)
|
||||
| <<10, source:bits>>, #(cps, parsed_type)
|
||||
| <<11, source:bits>>, #(cps, parsed_type)
|
||||
| <<12, source:bits>>, #(cps, parsed_type)
|
||||
| <<13, source:bits>>, #(cps, parsed_type)
|
||||
| <<34, _:bits>> as source, #(cps, parsed_type)
|
||||
| <<40, _:bits>> as source, #(cps, parsed_type)
|
||||
| <<41, _:bits>> as source, #(cps, parsed_type)
|
||||
-> {
|
||||
let str = cps |> list.reverse |> string.from_utf_codepoints
|
||||
case parsed_type {
|
||||
ParsedInt ->
|
||||
|
@ -298,7 +318,14 @@ fn do_name_number(
|
|||
Error(Nil) -> Ok(#(Name(str), source))
|
||||
}
|
||||
ParsedName -> Ok(#(Name(str), source))
|
||||
ParsedString -> Ok(#(String(str), source))
|
||||
}
|
||||
}
|
||||
<<cp:utf8_codepoint, rest:bits>>, #(cps, _) ->
|
||||
do_name_number(rest, #([cp, ..cps], ParsedString))
|
||||
source, #(_, _) ->
|
||||
Error(InvalidUtf8Character(
|
||||
source |> bit_array.slice(0, 4) |> result.unwrap(source),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import gleam/list
|
||||
import gleam/option.{type Option}
|
||||
import gleam/option.{type Option, None, Some}
|
||||
import gleam/pair
|
||||
import kicad_sexpr/decode.{type Decoder, type NextFn}
|
||||
|
||||
|
@ -19,7 +19,7 @@ fn allowed(then next: NextFn(Bool, a)) -> Decoder(a) {
|
|||
decode.enum(with: [#("allowed", True), #("not_allowed", False)], then: next)
|
||||
}
|
||||
|
||||
fn fill_flag(then next: NextFn(Bool, a)) -> Decoder(a) {
|
||||
fn filled(then next: NextFn(Bool, a)) -> Decoder(a) {
|
||||
decode.token_wrapper(named: "fill", with: yes_no, then: next)
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,11 @@ fn margins(then next: NextFn(#(Float, Float, Float, Float), a)) -> Decoder(a) {
|
|||
}
|
||||
|
||||
fn hide(then next: NextFn(Bool, a)) -> Decoder(a) {
|
||||
decode.token_wrapper(named: "hide", with: yes_no, then: next)
|
||||
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) {
|
||||
|
@ -65,14 +69,19 @@ fn custom_xy(named name: String, then next: NextFn(XY, a)) -> Decoder(a) {
|
|||
|
||||
fn layers(then next: NextFn(List(Layer), a)) -> Decoder(a) {
|
||||
decode.token(named: "layers", then: next, with: {
|
||||
use layers <- decode.list(decode.name_or_string)
|
||||
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))
|
||||
PositionIdentifier(
|
||||
x: Float,
|
||||
y: Float,
|
||||
angle: Option(Float),
|
||||
locked: Option(Bool),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn position_identifier(
|
||||
|
@ -82,7 +91,11 @@ pub fn position_identifier(
|
|||
use x <- decode.float()
|
||||
use y <- decode.float()
|
||||
use angle <- decode.optional(decode.float)
|
||||
decode.success(PositionIdentifier(x:, y:, angle:))
|
||||
use locked <- decode.optional(decode.enum(
|
||||
[#("locked", True), #("unlocked", False)],
|
||||
then: _,
|
||||
))
|
||||
decode.success(PositionIdentifier(x:, y:, angle:, locked:))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -257,19 +270,21 @@ pub fn stroke(then next: NextFn(Stroke, a)) -> Decoder(a) {
|
|||
|
||||
pub type FillType {
|
||||
NoFill
|
||||
SolidFillType
|
||||
OutlineFillType
|
||||
BackgroundFillType
|
||||
}
|
||||
|
||||
pub fn fill_type(then next: NextFn(FillType, a)) -> Decoder(a) {
|
||||
decode.token(named: "type", then: next, with: {
|
||||
use value <- decode.enum([
|
||||
decode.enum(
|
||||
[
|
||||
#("none", NoFill),
|
||||
#("solid", SolidFillType),
|
||||
#("outline", OutlineFillType),
|
||||
#("background", BackgroundFillType),
|
||||
])
|
||||
decode.success(value)
|
||||
})
|
||||
],
|
||||
then: next,
|
||||
)
|
||||
}
|
||||
|
||||
pub type Fill {
|
||||
|
@ -278,7 +293,10 @@ pub type Fill {
|
|||
|
||||
pub fn fill(then next: NextFn(Fill, a)) -> Decoder(a) {
|
||||
decode.token(named: "fill", then: next, with: {
|
||||
use type_ <- fill_type()
|
||||
use type_ <- decode.one_of(
|
||||
decode.token_wrapper(named: "type", with: fill_type, then: _),
|
||||
or: [fill_type],
|
||||
)
|
||||
decode.success(Fill(type_:))
|
||||
})
|
||||
}
|
||||
|
@ -315,14 +333,14 @@ pub fn font(then next: NextFn(Font, a)) -> Decoder(a) {
|
|||
))
|
||||
use size <- size()
|
||||
use thickness <- decode.optional(thickness)
|
||||
use bold <- decode.optional(decode.token_wrapper(
|
||||
named: "bold",
|
||||
with: yes_no,
|
||||
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.token_wrapper(
|
||||
named: "italic",
|
||||
with: yes_no,
|
||||
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(
|
||||
|
@ -497,7 +515,7 @@ pub type Timestamp {
|
|||
|
||||
pub fn timestamp(then next: NextFn(Timestamp, a)) -> Decoder(a) {
|
||||
decode.token(named: "tstamp", then: next, with: {
|
||||
use ts <- decode.name_string()
|
||||
use ts <- decode.string()
|
||||
decode.success(Timestamp(ts:))
|
||||
})
|
||||
}
|
||||
|
@ -508,7 +526,7 @@ pub type Layer {
|
|||
|
||||
pub fn layer(then next: NextFn(Layer, a)) -> Decoder(a) {
|
||||
decode.token(named: "layer", then: next, with: {
|
||||
use layer <- decode.name_or_string()
|
||||
use layer <- decode.name_string()
|
||||
decode.success(Layer(layer:))
|
||||
})
|
||||
}
|
||||
|
@ -671,7 +689,7 @@ pub type FootprintText {
|
|||
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.string()
|
||||
use text <- decode.name_string()
|
||||
use position <- position_identifier()
|
||||
use unlocked <- decode.optional(decode.token_wrapper(
|
||||
named: "unlocked",
|
||||
|
@ -734,7 +752,7 @@ pub fn footprint_text_box(then next: NextFn(FootprintTextBox, a)) -> Decoder(a)
|
|||
then: _,
|
||||
))
|
||||
use stroke <- decode.optional(stroke)
|
||||
let render_cache = option.None
|
||||
let render_cache = None
|
||||
use timestamp <- decode.optional(timestamp)
|
||||
decode.success(FootprintTextBox(
|
||||
locked:,
|
||||
|
@ -796,8 +814,10 @@ pub type FootprintRectangle {
|
|||
start: XY,
|
||||
end: XY,
|
||||
stroke: Option(Stroke),
|
||||
fill: Option(Bool),
|
||||
filled: Option(Bool),
|
||||
layer: Layer,
|
||||
fill: Option(Fill),
|
||||
width: Option(Float),
|
||||
locked: Bool,
|
||||
uuid: Option(Uuid),
|
||||
timestamp: Option(Timestamp),
|
||||
|
@ -811,8 +831,12 @@ pub fn footprint_rectangle(
|
|||
use start <- custom_xy("start")
|
||||
use end <- custom_xy("end")
|
||||
use stroke <- decode.optional(stroke)
|
||||
use fill <- decode.optional(fill_flag)
|
||||
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)
|
||||
|
@ -820,8 +844,10 @@ pub fn footprint_rectangle(
|
|||
start:,
|
||||
end:,
|
||||
stroke:,
|
||||
fill:,
|
||||
filled:,
|
||||
layer:,
|
||||
fill:,
|
||||
width:,
|
||||
locked:,
|
||||
uuid:,
|
||||
timestamp:,
|
||||
|
@ -834,8 +860,10 @@ pub type FootprintCircle {
|
|||
center: XY,
|
||||
end: XY,
|
||||
stroke: Option(Stroke),
|
||||
fill: Option(Bool),
|
||||
filled: Option(Bool),
|
||||
layer: Layer,
|
||||
fill: Option(Fill),
|
||||
width: Option(Float),
|
||||
locked: Bool,
|
||||
uuid: Option(Uuid),
|
||||
timestamp: Option(Timestamp),
|
||||
|
@ -847,8 +875,12 @@ pub fn footprint_circle(then next: NextFn(FootprintCircle, a)) -> Decoder(a) {
|
|||
use center <- custom_xy("center")
|
||||
use end <- custom_xy("end")
|
||||
use stroke <- decode.optional(stroke)
|
||||
use fill <- decode.optional(fill_flag)
|
||||
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)
|
||||
|
@ -856,8 +888,10 @@ pub fn footprint_circle(then next: NextFn(FootprintCircle, a)) -> Decoder(a) {
|
|||
center:,
|
||||
end:,
|
||||
stroke:,
|
||||
fill:,
|
||||
filled:,
|
||||
layer:,
|
||||
fill:,
|
||||
width:,
|
||||
locked:,
|
||||
uuid:,
|
||||
timestamp:,
|
||||
|
@ -872,6 +906,7 @@ pub type FootprintArc {
|
|||
end: XY,
|
||||
stroke: Option(Stroke),
|
||||
layer: Layer,
|
||||
width: Option(Float),
|
||||
locked: Bool,
|
||||
uuid: Option(Uuid),
|
||||
timestamp: Option(Timestamp),
|
||||
|
@ -885,6 +920,7 @@ pub fn footprint_arc(then next: NextFn(FootprintArc, a)) -> Decoder(a) {
|
|||
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)
|
||||
|
@ -894,6 +930,7 @@ pub fn footprint_arc(then next: NextFn(FootprintArc, a)) -> Decoder(a) {
|
|||
end:,
|
||||
stroke:,
|
||||
layer:,
|
||||
width:,
|
||||
locked:,
|
||||
uuid:,
|
||||
timestamp:,
|
||||
|
@ -905,8 +942,10 @@ pub type FootprintPolygon {
|
|||
FootprintPolygon(
|
||||
points: PolyPoints,
|
||||
stroke: Option(Stroke),
|
||||
fill: Option(Bool),
|
||||
filled: Option(Bool),
|
||||
layer: Layer,
|
||||
fill: Option(Fill),
|
||||
width: Option(Float),
|
||||
locked: Bool,
|
||||
uuid: Option(Uuid),
|
||||
timestamp: Option(Timestamp),
|
||||
|
@ -917,16 +956,22 @@ 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 fill <- decode.optional(fill_flag)
|
||||
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:,
|
||||
fill:,
|
||||
filled:,
|
||||
layer:,
|
||||
fill:,
|
||||
width:,
|
||||
locked:,
|
||||
uuid:,
|
||||
timestamp:,
|
||||
|
@ -939,6 +984,7 @@ pub type FootprintCurve {
|
|||
points: Points,
|
||||
stroke: Option(Stroke),
|
||||
layer: Layer,
|
||||
width: Option(Float),
|
||||
locked: Bool,
|
||||
uuid: Option(Uuid),
|
||||
timestamp: Option(Timestamp),
|
||||
|
@ -950,6 +996,7 @@ pub fn footprint_curve(then next: NextFn(FootprintCurve, a)) -> Decoder(a) {
|
|||
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)
|
||||
|
@ -957,6 +1004,7 @@ pub fn footprint_curve(then next: NextFn(FootprintCurve, a)) -> Decoder(a) {
|
|||
points:,
|
||||
stroke:,
|
||||
layer:,
|
||||
width:,
|
||||
locked:,
|
||||
uuid:,
|
||||
timestamp:,
|
||||
|
@ -1334,7 +1382,7 @@ pub fn graphical_text_box(then next: NextFn(GraphicalTextBox, a)) -> Decoder(a)
|
|||
use uuid <- decode.optional(uuid)
|
||||
use effects <- effects()
|
||||
use stroke <- decode.optional(stroke)
|
||||
let render_cache = option.None
|
||||
let render_cache = None
|
||||
decode.success(GraphicalTextBox(
|
||||
locked:,
|
||||
text:,
|
||||
|
@ -1393,7 +1441,7 @@ pub fn graphical_rectangle(
|
|||
use end <- custom_xy("end")
|
||||
use layer <- decode.optional(layer)
|
||||
use width <- width()
|
||||
use fill <- decode.optional(fill_flag)
|
||||
use fill <- decode.optional(filled)
|
||||
use uuid <- decode.optional(uuid)
|
||||
decode.success(GraphicalRectangle(
|
||||
start:,
|
||||
|
@ -1423,7 +1471,7 @@ pub fn graphical_circle(then next: NextFn(GraphicalCircle, a)) -> Decoder(a) {
|
|||
use end <- custom_xy("end")
|
||||
use layer <- decode.optional(layer)
|
||||
use width <- width()
|
||||
use fill <- decode.optional(fill_flag)
|
||||
use fill <- decode.optional(filled)
|
||||
use uuid <- decode.optional(uuid)
|
||||
decode.success(GraphicalCircle(center:, end:, layer:, width:, fill:, uuid:))
|
||||
})
|
||||
|
@ -1467,7 +1515,7 @@ pub fn graphical_polygon(then next: NextFn(GraphicalPolygon, a)) -> Decoder(a) {
|
|||
use points <- poly_points()
|
||||
use layer <- decode.optional(layer)
|
||||
use width <- width()
|
||||
use fill <- decode.optional(fill_flag)
|
||||
use fill <- decode.optional(filled)
|
||||
use uuid <- decode.optional(uuid)
|
||||
decode.success(GraphicalPolygon(points:, layer:, width:, fill:, uuid:))
|
||||
})
|
||||
|
@ -1780,12 +1828,7 @@ pub fn symbol_pin(then next: NextFn(SymbolPin, a)) -> Decoder(a) {
|
|||
use graphical_style <- pin_graphical_style()
|
||||
use position <- position_identifier()
|
||||
use length <- decode.token_wrapper(named: "length", with: decode.float)
|
||||
use hide_flag <- decode.flag("hide")
|
||||
use hide <-
|
||||
case hide_flag {
|
||||
True -> decode.of(with: decode.success(option.Some(True)), then: _)
|
||||
False -> decode.optional(hide, then: _)
|
||||
}
|
||||
use hide <- decode.optional(hide)
|
||||
use name <- pin_name()
|
||||
use number <- pin_number()
|
||||
use alternatives <- decode.list(pin_alternate)
|
||||
|
@ -2005,7 +2048,7 @@ pub fn custom_pad_primitives(
|
|||
decode.token(named: "primitives", then: next, with: {
|
||||
use graphic_items <- decode.list(graphic_item)
|
||||
use width <- decode.optional(width)
|
||||
use fill <- decode.optional(fill_flag)
|
||||
use fill <- decode.optional(filled)
|
||||
decode.success(CustomPadPrimitives(graphic_items:, width:, fill:))
|
||||
})
|
||||
}
|
||||
|
@ -2049,7 +2092,7 @@ pub type Pad {
|
|||
|
||||
pub fn pad(then next: NextFn(Pad, a)) -> Decoder(a) {
|
||||
decode.token(named: "pad", then: next, with: {
|
||||
use number <- decode.string()
|
||||
use number <- decode.name_number_string()
|
||||
use type_ <- pad_type()
|
||||
use shape <- pad_shape()
|
||||
use position <- position_identifier()
|
||||
|
@ -2065,14 +2108,16 @@ pub fn pad(then next: NextFn(Pad, a)) -> Decoder(a) {
|
|||
use layers <- layers()
|
||||
use remove_unused_layers <- decode.optional(decode.token_wrapper(
|
||||
named: "remove_unused_layers",
|
||||
with: yes_no,
|
||||
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: yes_no,
|
||||
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,
|
||||
|
@ -2485,6 +2530,7 @@ pub type Zone {
|
|||
net_name: String,
|
||||
layers: List(Layer),
|
||||
uuid: Option(Uuid),
|
||||
timestamp: Option(Timestamp),
|
||||
name: Option(String),
|
||||
hatch: Hatch,
|
||||
priority: Option(Int),
|
||||
|
@ -2506,6 +2552,7 @@ pub fn zone(then next: NextFn(Zone, a)) -> Decoder(a) {
|
|||
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,
|
||||
|
@ -2538,6 +2585,7 @@ pub fn zone(then next: NextFn(Zone, a)) -> Decoder(a) {
|
|||
net_name:,
|
||||
layers:,
|
||||
uuid:,
|
||||
timestamp:,
|
||||
name:,
|
||||
hatch:,
|
||||
priority:,
|
||||
|
@ -2585,7 +2633,10 @@ 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.token_wrapper(named: "offset", with: xyz)
|
||||
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:))
|
||||
|
@ -2635,7 +2686,7 @@ fn base_footprint(then next: NextFn(Footprint, a)) -> Decoder(a) {
|
|||
use layer <- layer()
|
||||
use tedit <- decode.optional(decode.token_wrapper(
|
||||
named: "tedit",
|
||||
with: decode.name_or_string,
|
||||
with: decode.name_number_string,
|
||||
then: _,
|
||||
))
|
||||
use uuid <- decode.optional(uuid)
|
||||
|
@ -2656,6 +2707,7 @@ fn base_footprint(then next: NextFn(Footprint, a)) -> Decoder(a) {
|
|||
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,
|
||||
|
@ -2708,7 +2760,8 @@ fn base_footprint(then next: NextFn(Footprint, a)) -> Decoder(a) {
|
|||
with: decode.float,
|
||||
then: _,
|
||||
))
|
||||
use attributes <- decode.optional(footprint_attributes)
|
||||
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: _),
|
||||
|
@ -2719,8 +2772,10 @@ fn base_footprint(then next: NextFn(Footprint, a)) -> Decoder(a) {
|
|||
with: decode.list(decode.string, then: _),
|
||||
then: _,
|
||||
))
|
||||
use graphic_items <- decode.list(footprint_graphic_item)
|
||||
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(
|
||||
|
@ -2771,21 +2826,26 @@ pub fn footprint(then next: NextFn(Footprint, a)) -> Decoder(a) {
|
|||
pub type FootprintFile {
|
||||
FootprintFile(
|
||||
name: String,
|
||||
version: Int,
|
||||
generator: 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.token(named: "footprint", then: next, with: {
|
||||
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_or_string,
|
||||
with: decode.name_string,
|
||||
)
|
||||
let generator = Some(generator)
|
||||
use generator_version <- decode.optional(decode.token_wrapper(
|
||||
named: "generator_version",
|
||||
with: decode.string,
|
||||
|
@ -2799,7 +2859,31 @@ pub fn footprint_file(then next: NextFn(FootprintFile, a)) -> Decoder(a) {
|
|||
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 {
|
||||
|
@ -2863,7 +2947,7 @@ pub type Symbol {
|
|||
|
||||
fn base_symbol(then next: NextFn(Symbol, a)) -> Decoder(a) {
|
||||
decode.of(then: next, with: {
|
||||
use library_unit_id <- decode.string
|
||||
use library_unit_id <- decode.string()
|
||||
use extends <- decode.optional(decode.token_wrapper(
|
||||
named: "extends",
|
||||
with: decode.string,
|
||||
|
@ -2963,7 +3047,7 @@ pub fn symbol_library(then next: NextFn(SymbolLibrary, a)) -> Decoder(a) {
|
|||
use version <- decode.token_wrapper(named: "version", with: decode.int)
|
||||
use generator <- decode.token_wrapper(
|
||||
named: "generator",
|
||||
with: decode.string,
|
||||
with: decode.name_string,
|
||||
)
|
||||
use generator_version <- decode.optional(decode.token_wrapper(
|
||||
named: "generator_version",
|
||||
|
|
|
@ -2,8 +2,6 @@ import gleam/float
|
|||
import gleam/int
|
||||
import gleam/io
|
||||
import gleam/list
|
||||
|
||||
// import gleam/pair
|
||||
import gleam/result
|
||||
import gleam/string
|
||||
import gleam/time/duration
|
||||
|
@ -18,21 +16,19 @@ pub fn main() -> Nil {
|
|||
io.println("\nTesting Footprints")
|
||||
let assert Ok(footprint_files) =
|
||||
simplifile.get_files("/usr/share/kicad/footprints")
|
||||
// test_read_parse_decode(
|
||||
// footprint_files |> list.drop(0) |> list.split(10) |> pair.first,
|
||||
// token.footprint_file,
|
||||
// True,
|
||||
// )
|
||||
// test_read_parse_decode(
|
||||
// ["test_files/test3.kicad_mod"],
|
||||
// token.footprint_file,
|
||||
// True,
|
||||
// )
|
||||
test_read_parse_decode(footprint_files, token.footprint_file, False)
|
||||
// let footprint_files = footprint_files |> list.drop(0) |> list.take(5000)
|
||||
// let footprint_files = footprint_files |> list.sample(1000)
|
||||
// let footprint_files = ["test_files/test3.kicad_mod"]
|
||||
test_read_parse_decode(footprint_files, token.footprint_file, True)
|
||||
|
||||
io.println("\nTesting Symbol Libraries")
|
||||
let assert Ok(symbol_libraries) =
|
||||
simplifile.get_files("/usr/share/kicad/symbols")
|
||||
test_read_parse_decode(symbol_libraries, token.symbol_library, False)
|
||||
// let symbol_libraries = symbol_libraries |> list.drop(0) |> list.take(20)
|
||||
// let symbol_libraries = symbol_libraries |> list.sample(1000)
|
||||
// let symbol_libraries = ["test_files/test3.kicad_mod"]
|
||||
test_read_parse_decode(symbol_libraries, token.symbol_library, True)
|
||||
|
||||
gleeunit.main()
|
||||
}
|
||||
|
||||
|
@ -50,20 +46,23 @@ fn print_stats(
|
|||
title: String,
|
||||
successes: Int,
|
||||
total: Int,
|
||||
num_len: Int,
|
||||
start_time: Timestamp,
|
||||
end_time: Timestamp,
|
||||
) -> Nil {
|
||||
io.println(
|
||||
title
|
||||
<> int.to_string(successes)
|
||||
<> { int.to_string(successes) |> string.pad_start(num_len, "0") }
|
||||
<> "/"
|
||||
<> int.to_string(total)
|
||||
<> { int.to_string(total) |> string.pad_start(num_len, "0") }
|
||||
<> " ("
|
||||
<> int.to_float(100 * successes) /. int.to_float(total)
|
||||
<> {
|
||||
int.to_float(100 * successes) /. int.to_float(total)
|
||||
|> float.to_precision(1)
|
||||
|> float.to_string
|
||||
|> string.pad_start(5, "0")
|
||||
|> string.append("%")
|
||||
}
|
||||
<> ") in "
|
||||
<> time_taken_string(start_time, end_time),
|
||||
)
|
||||
|
@ -75,7 +74,9 @@ fn test_read_parse_decode(
|
|||
print_errors: Bool,
|
||||
) -> Nil {
|
||||
let num_file_names = list.length(file_names)
|
||||
io.println("Total: " <> int.to_string(num_file_names))
|
||||
let num_file_names_str = int.to_string(num_file_names)
|
||||
let num_len = string.length(num_file_names_str)
|
||||
io.println("Total: " <> num_file_names_str)
|
||||
|
||||
let time_before_read = timestamp.system_time()
|
||||
let #(successfully_read, failed_to_read) =
|
||||
|
@ -92,6 +93,7 @@ fn test_read_parse_decode(
|
|||
"Read: ",
|
||||
num_successfully_read,
|
||||
num_file_names,
|
||||
num_len,
|
||||
time_before_read,
|
||||
time_after_read,
|
||||
)
|
||||
|
@ -121,6 +123,7 @@ fn test_read_parse_decode(
|
|||
"Parsed: ",
|
||||
num_successfully_parsed,
|
||||
num_successfully_read,
|
||||
num_len,
|
||||
time_before_parse,
|
||||
time_after_parse,
|
||||
)
|
||||
|
@ -150,6 +153,7 @@ fn test_read_parse_decode(
|
|||
"Decoded: ",
|
||||
num_successfully_decoded,
|
||||
num_successfully_parsed,
|
||||
num_len,
|
||||
time_before_decode,
|
||||
time_after_decode,
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue