chore: bootstrap crate scaffold and proto build pipeline

This commit is contained in:
Milind Sharma 2026-02-18 22:37:51 +08:00
parent 367d550355
commit d1a4d553a1
32 changed files with 4113 additions and 3 deletions

1
.gitignore vendored
View File

@ -20,7 +20,6 @@ target
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
proto/
prompts/ prompts/
*.DS_Store *.DS_Store

716
Cargo.lock generated Normal file
View File

@ -0,0 +1,716 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
[[package]]
name = "bitflags"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]]
name = "bytes"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
[[package]]
name = "cc"
version = "1.2.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cmake"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d"
dependencies = [
"cc",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "fixedbitset"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "getrandom"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasip2",
"wasip3",
]
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"foldhash",
]
[[package]]
name = "hashbrown"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "id-arena"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
[[package]]
name = "indexmap"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [
"equivalent",
"hashbrown 0.16.1",
"serde",
"serde_core",
]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "kicad-ipc"
version = "0.0.0"
dependencies = [
"nng",
"prost",
"prost-build",
"prost-types",
"thiserror",
"tokio",
"tracing",
]
[[package]]
name = "leb128fmt"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "libc"
version = "0.2.182"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
[[package]]
name = "linux-raw-sys"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "multimap"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
[[package]]
name = "nng"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20a18ed7ec1c8ff1658bcfea2ce76dcedf8be21dd9e8dd2e9762ba9632d16203"
dependencies = [
"log",
"nng-sys",
]
[[package]]
name = "nng-sys"
version = "1.4.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d0e7f39a8fd1792a710da9351320e864dc799cf439960e332c977b2f876da6"
dependencies = [
"cmake",
"version_check",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "petgraph"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
dependencies = [
"fixedbitset",
"hashbrown 0.15.5",
"indexmap",
]
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "prettyplease"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "prost"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
dependencies = [
"bytes",
"prost-derive",
]
[[package]]
name = "prost-build"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7"
dependencies = [
"heck",
"itertools",
"log",
"multimap",
"petgraph",
"prettyplease",
"prost",
"prost-types",
"regex",
"syn",
"tempfile",
]
[[package]]
name = "prost-derive"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
dependencies = [
"anyhow",
"itertools",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "prost-types"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7"
dependencies = [
"prost",
]
[[package]]
name = "quote"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "regex"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c"
[[package]]
name = "rustix"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "semver"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.116"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tempfile"
version = "3.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1"
dependencies = [
"fastrand",
"getrandom",
"once_cell",
"rustix",
"windows-sys",
]
[[package]]
name = "thiserror"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio"
version = "1.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
dependencies = [
"pin-project-lite",
"tokio-macros",
]
[[package]]
name = "tokio-macros"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
dependencies = [
"once_cell",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "unicode-xid"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasip2"
version = "1.0.2+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasip3"
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-encoder"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
dependencies = [
"leb128fmt",
"wasmparser",
]
[[package]]
name = "wasm-metadata"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
dependencies = [
"anyhow",
"indexmap",
"wasm-encoder",
"wasmparser",
]
[[package]]
name = "wasmparser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
dependencies = [
"bitflags",
"hashbrown 0.15.5",
"indexmap",
"semver",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "wit-bindgen"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
dependencies = [
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
dependencies = [
"anyhow",
"heck",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
dependencies = [
"anyhow",
"heck",
"indexmap",
"prettyplease",
"syn",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
dependencies = [
"anyhow",
"prettyplease",
"proc-macro2",
"quote",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
]
[[package]]
name = "wit-component"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
dependencies = [
"anyhow",
"bitflags",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-encoder",
"wasm-metadata",
"wasmparser",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"semver",
"serde",
"serde_derive",
"serde_json",
"unicode-xid",
"wasmparser",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"

25
Cargo.toml Normal file
View File

@ -0,0 +1,25 @@
[package]
name = "kicad-ipc"
version = "0.0.0"
edition = "2021"
license = "MIT"
description = "Rust bindings for the KiCad IPC API"
repository = "https://github.com/kicad-oss/kicad-ipc-rust"
readme = "README.md"
[features]
default = ["async"]
async = ["dep:nng", "dep:prost", "dep:prost-types", "dep:tokio"]
blocking = ["async"]
tracing = ["dep:tracing"]
[dependencies]
nng = { version = "1.0.1", optional = true }
prost = { version = "0.14.3", optional = true }
prost-types = { version = "0.14.1", optional = true }
thiserror = "2.0.12"
tokio = { version = "1.48.0", features = ["sync", "time", "rt", "macros"], optional = true }
tracing = { version = "0.1.41", optional = true }
[build-dependencies]
prost-build = "0.14.1"

View File

@ -1,2 +1,15 @@
# KiCAD IPC API Rust # KiCad IPC API Rust
MIT licensed, entirely up-to-date, actively maintained Rust bindings for the KiCAD IPC API
MIT-licensed Rust bindings for the KiCad IPC API.
## Current Status
Early scaffold phase. Core architecture + step-by-step implementation plan:
- `/Users/milindsharma/Developer/kicad-oss/kicad-ipc-rust/prompts/IPC_RUST_EXECUTION_PLAN.md`
- `/Users/milindsharma/Developer/kicad-oss/kicad-ipc-rust/proto/README.md`
## Roadmap
1. Async-first layered client (`v0.1.0`)
2. Full PCB read surface + trace write capability (`v0.1.0`)
3. Blocking wrapper parity (`v0.2.0`)

38
build.rs Normal file
View File

@ -0,0 +1,38 @@
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
fn collect_proto_files(root: &Path, out: &mut Vec<PathBuf>) -> io::Result<()> {
for entry in fs::read_dir(root)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
collect_proto_files(&path, out)?;
continue;
}
if path.extension().and_then(|ext| ext.to_str()) == Some("proto") {
out.push(path);
}
}
Ok(())
}
fn main() {
let proto_root = PathBuf::from("proto");
println!("cargo:rerun-if-changed={}", proto_root.display());
let mut proto_files = Vec::new();
collect_proto_files(&proto_root, &mut proto_files)
.expect("failed to enumerate proto files under ./proto");
proto_files.sort();
let mut config = prost_build::Config::new();
config.protoc_arg("--experimental_allow_proto3_optional");
config
.compile_protos(&proto_files, &[proto_root])
.expect("failed to compile KiCad protobuf schema");
}

17
proto/README.md Normal file
View File

@ -0,0 +1,17 @@
# KiCad IPC Protocol Buffer Definitions
These `.proto` files are copied from the official KiCad source tree:
- https://gitlab.com/kicad/code/kicad/-/tree/master/api/proto
Rules for this repository:
1. Keep copied files verbatim when possible.
2. Preserve original upstream copyright/license headers.
3. Use these files for build-time code generation.
4. Do not commit generated Rust protobuf output.
Crate licensing:
- Hand-written Rust code in this repository is MIT licensed.
- Upstream `.proto` files retain their original upstream licensing/headers.

146
proto/board/board.proto Normal file
View File

@ -0,0 +1,146 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
syntax = "proto3";
package kiapi.board;
import "common/types/base_types.proto";
import "board/board_types.proto";
message BoardFinish
{
string type_name = 1;
}
message BoardImpedanceControl
{
bool is_controlled = 1;
}
message BoardEdgeConnector
{
}
message Castellation
{
bool has_castellated_pads = 1;
}
message EdgePlating
{
bool has_edge_plating = 1;
}
message BoardEdgeSettings
{
BoardEdgeConnector connector = 1;
Castellation castellation = 2;
EdgePlating plating = 3;
}
message BoardStackupCopperLayer
{
}
enum BoardStackupLayerType
{
BSLT_UNKNOWN = 0;
BSLT_COPPER = 1;
BSLT_DIELECTRIC = 2;
BSLT_SILKSCREEN = 3;
BSLT_SOLDERMASK = 4;
BSLT_SOLDERPASTE = 5;
BSLT_UNDEFINED = 7;
}
message BoardStackupDielectricProperties
{
double epsilon_r = 1;
double loss_tangent = 2;
string material_name = 3;
kiapi.common.types.Distance thickness = 4;
}
message BoardStackupDielectricLayer
{
// A single dielectric slot (between copper layers) can be made up of multiple physical layers
repeated BoardStackupDielectricProperties layer = 1;
}
message BoardStackupLayer
{
kiapi.common.types.Distance thickness = 1;
kiapi.board.types.BoardLayer layer = 2;
bool enabled = 3;
BoardStackupLayerType type = 4;
BoardStackupDielectricLayer dielectric = 5;
kiapi.common.types.Color color = 6;
string material_name = 7;
// The name of the layer shown in the KiCad GUI, which may be a default value like "F.Cu" or may
// have been customized by the user. This field does not apply to dielectric layers.
string user_name = 8;
}
message BoardStackup
{
BoardFinish finish = 1;
BoardImpedanceControl impedance = 2;
// NOTE: m_HasThicknessConstrains appears to be unused
BoardEdgeSettings edge = 3;
repeated BoardStackupLayer layers = 4;
}
// LAYER_CLASS_* in BOARD_DESIGN_SETTINGS -- needs to become an enum class
enum BoardLayerClass
{
BLC_UNKNOWN = 0;
BLC_SILKSCREEN = 1;
BLC_COPPER = 2;
BLC_EDGES = 3;
BLC_COURTYARD = 4;
BLC_FABRICATION = 5;
BLC_OTHER = 6;
}
message BoardLayerGraphicsDefaults
{
BoardLayerClass layer = 1;
kiapi.common.types.TextAttributes text = 2;
kiapi.common.types.Distance line_thickness = 3;
}
message GraphicsDefaults
{
repeated BoardLayerGraphicsDefaults layers = 1;
}
// Anything that isn't stackup or design rules
message BoardSettings
{
GraphicsDefaults graphics_defaults = 1;
// Dimension default settings
}
message BoardDesignRules
{
}

View File

@ -0,0 +1,412 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
syntax = "proto3";
package kiapi.board.commands;
import "common/types/base_types.proto";
import "common/types/enums.proto";
import "common/types/project_settings.proto";
import "board/board.proto";
import "board/board_types.proto";
/*
* Board stackup and properties
*/
message GetBoardStackup
{
kiapi.common.types.DocumentSpecifier board = 1;
}
message BoardStackupResponse
{
kiapi.board.BoardStackup stackup = 1;
}
// Changes the stackup for the given board according to the contents of the message (**not yet implemented**)
// WARNING: any existing content on layers that are removed by this call is deleted. This operation cannot be undone.
// Returns BoardStackupResponse with the updated stackup, in normalized form
message UpdateBoardStackup
{
kiapi.common.types.DocumentSpecifier board = 1;
kiapi.board.BoardStackup stackup = 2;
}
message GetBoardEnabledLayers
{
kiapi.common.types.DocumentSpecifier board = 1;
}
message BoardEnabledLayersResponse
{
// The number of copper layers enabled in this board.
uint32 copper_layer_count = 1;
// A list of all layers enabled in this board, including copper layers and ones which cannot be disabled.
repeated kiapi.board.types.BoardLayer layers = 2;
}
// Changes which layers are enabled in the board stackup
// WARNING: any existing content on layers that are removed by this call is deleted. This operation cannot be undone.
// Returns BoardEnabledLayersResponse with the updated layer set.
message SetBoardEnabledLayers
{
kiapi.common.types.DocumentSpecifier board = 1;
// The number of copper layers to enable in the board. Currently, this must be an even number >= 2.
uint32 copper_layer_count = 2;
// The non-copper layers to enable. Note that any copper layers in this list are ignored; copper layers are enabled
// by setting copper_layer_count. Note that the F/B.Courtyard, Edge.Cuts, and Margin layers cannot be disabled and
// will be present in the board even if they are omitted from this list.
repeated kiapi.board.types.BoardLayer layers = 3;
}
message GetGraphicsDefaults
{
kiapi.common.types.DocumentSpecifier board = 1;
}
message GraphicsDefaultsResponse
{
kiapi.board.GraphicsDefaults defaults = 1;
}
enum BoardOriginType
{
BOT_UNKNOWN = 0;
BOT_GRID = 1;
BOT_DRILL = 2;
}
// Returns a Vector2 with the specified origin point
message GetBoardOrigin
{
kiapi.common.types.DocumentSpecifier board = 1;
BoardOriginType type = 2;
}
message SetBoardOrigin
{
kiapi.common.types.DocumentSpecifier board = 1;
BoardOriginType type = 2;
kiapi.common.types.Vector2 origin = 3;
}
/*
* Net management
*/
message GetNets
{
kiapi.common.types.DocumentSpecifier board = 1;
// If provided, will only return nets that belong to the given netclass.
// If more than one netclass_filter is given, nets belonging to any of the given classes will
// be returned.
repeated string netclass_filter = 2;
}
message NetsResponse
{
repeated kiapi.board.types.Net nets = 1;
}
// Retrieve all the copper items belonging to a certain net or set of nets
// returns kiapi.common.commands.GetItemsResponse
message GetItemsByNet
{
// Specifies which document to query, which fields to return, etc.
kiapi.common.types.ItemHeader header = 1;
// List of one or more types of items to retreive
repeated kiapi.common.types.KiCadObjectType types = 2;
// A list of net codes to filter items by
repeated kiapi.board.types.NetCode net_codes = 3;
}
// Retrieve all the copper items belonging to a certain net class or set of net classes
// returns kiapi.common.commands.GetItemsResponse
message GetItemsByNetClass
{
// Specifies which document to query, which fields to return, etc.
kiapi.common.types.ItemHeader header = 1;
// List of one or more types of items to retreive
repeated kiapi.common.types.KiCadObjectType types = 2;
// A list of net class names to filter items by
repeated string net_classes = 3;
}
// A net may be part of multiple classes that have a priority ordering, which will result in a
// composite "effective" netclass containing the merged/overridden properties of all the constituent
// netclasses it contains. This message retrieves this effective netclass for a net or list of
// nets.
// Returns NetClassForNetsResponse
message GetNetClassForNets
{
repeated kiapi.board.types.Net net = 1;
}
message NetClassForNetsResponse
{
// Map of net name to netclass info
map<string, kiapi.common.project.NetClass> classes = 1;
}
/*
* Blocking operations
*/
// Refills some or all zones on the board.
// This is a blocking operation; it will return Empty immediately, but KiCad will return
// ApiStatusCode.AS_BUSY to all future API requests until the zone fill has completed.
message RefillZones
{
kiapi.common.types.DocumentSpecifier board = 1;
// A list of zones to refill. If empty, all zones are refilled.
repeated kiapi.common.types.KIID zones = 2;
}
/*
* Utilities
*/
// Computes the polygon representation of a pad, merging any custom shapes together.
// This representation will approximate curves as a series of segments.
message GetPadShapeAsPolygon
{
// The board to process
kiapi.common.types.DocumentSpecifier board = 1;
// A list of one or more pads to process
repeated kiapi.common.types.KIID pads = 2;
// The layer to process
kiapi.board.types.BoardLayer layer = 3;
}
// Returned from GetPadShapeAsPolygon. The pads and polygons repeated fields will have the same length
// and can be treated as a list of tuples.
message PadShapeAsPolygonResponse
{
// The pads that were processed
repeated kiapi.common.types.KIID pads = 1;
// The polygon representation of each pad
repeated kiapi.common.types.PolygonWithHoles polygons = 2;
}
// Tests if the given set of items with padstacks (pads or vias) has content on the given set of layers.
// This is a dynamic call rather than a property of the padstack because pads and vias can be set to only include
// shapes on connected copper layers, and whether or not the pad is connected can't be determined in isolation.
// To optimize API call performance, multiple items and multiple layers to test may be passed in with this
// command message. The return will include the results for each valid item on each valid layer.
// Note that not all layers make sense for a given item (for example, testing against BL_UNDEFINED never makes
// sense). In general, the internal KiCad APIs will not return an error when testing non-sensical layers for a given
// item, and instead will return a default of "true" for any such layers.
message CheckPadstackPresenceOnLayers
{
kiapi.common.types.DocumentSpecifier board = 1;
repeated kiapi.common.types.KIID items = 2;
repeated kiapi.board.types.BoardLayer layers = 3;
}
enum PadstackPresence
{
PSP_UNKNOWN = 0;
PSP_PRESENT = 1; // The padstack has a shape on a given layer (is flashed)
PSP_NOT_PRESENT = 2; // The padstack has no shape on a given layer (is not flashed)
}
message PadstackPresenceEntry
{
kiapi.common.types.KIID item = 1;
kiapi.board.types.BoardLayer layer = 2;
PadstackPresence presence = 3;
}
message PadstackPresenceResponse
{
repeated PadstackPresenceEntry entries = 1;
}
// DRC markers
enum DrcSeverity // Since 10.0
{
DRS_UNKNOWN = 0;
DRS_WARNING = 1;
DRS_ERROR = 2;
DRS_EXCLUSION = 3;
DRS_IGNORE = 4;
DRS_INFO = 5;
DRS_ACTION = 6;
DRS_DEBUG = 7;
DRS_UNDEFINED = 8;
}
// Returns InjectDrcErrorResponse
message InjectDrcError
{
kiapi.common.types.DocumentSpecifier board = 1;
DrcSeverity severity = 2;
string message = 3;
kiapi.common.types.Vector2 position = 4;
repeated kiapi.common.types.KIID items = 5;
}
message InjectDrcErrorResponse
{
kiapi.common.types.KIID marker = 1;
}
// PCB editor commands
// returns BoardLayers
message GetVisibleLayers
{
kiapi.common.types.DocumentSpecifier board = 1;
}
message BoardLayerResponse
{
kiapi.board.types.BoardLayer layer = 1;
}
message BoardLayers
{
repeated kiapi.board.types.BoardLayer layers = 1;
}
message SetVisibleLayers
{
kiapi.common.types.DocumentSpecifier board = 1;
repeated kiapi.board.types.BoardLayer layers = 2;
}
// returns BoardLayerResponse
message GetActiveLayer
{
kiapi.common.types.DocumentSpecifier board = 1;
}
message SetActiveLayer
{
kiapi.common.types.DocumentSpecifier board = 1;
kiapi.board.types.BoardLayer layer = 2;
}
enum InactiveLayerDisplayMode
{
ILDM_UNKNOWN = 0;
// Inactive layers are shown
ILDM_NORMAL = 1;
// Inactive layers are shown with dimmed colors
ILDM_DIMMED = 2;
// Inactive layers are hidden
ILDM_HIDDEN = 3;
}
enum NetColorDisplayMode
{
NCDM_UNKNOWN = 0;
// Net and netclass colors are shown in the ratsnest and on all copper items
NCDM_ALL = 1;
// Net and netclass colors are shown in the ratsnest only
NCDM_RATSNEST = 2;
// Net and netclass colors are not shown
NCDM_OFF = 3;
}
enum BoardFlipMode
{
BFM_UNKNOWN = 0;
// Normal ("non-flipped") mode
BFM_NORMAL = 1;
// "Flipped" mode, viewed from the back and mirrored around the X axis
BFM_FLIPPED_X = 2;
}
enum RatsnestDisplayMode
{
RDM_UNKNOWN = 0;
// Ratsnest lines are drawn to objects even if they are on hidden layers
RDM_ALL_LAYERS = 1;
// Ratsnest lines are hidden when at least one endpoint is an item on a hidden layer
RDM_VISIBLE_LAYERS = 2;
}
message BoardEditorAppearanceSettings
{
InactiveLayerDisplayMode inactive_layer_display = 1;
NetColorDisplayMode net_color_display = 2;
BoardFlipMode board_flip = 3;
RatsnestDisplayMode ratsnest_display = 4;
}
// Returns BoardEditorAppearanceSettings
message GetBoardEditorAppearanceSettings
{
}
message SetBoardEditorAppearanceSettings
{
BoardEditorAppearanceSettings settings = 1;
}
//// Interactive commands ////
// These commands begin an interactive operation in the editor.
// They return a response immediately, but the editor will become busy
// and will not reply to further API commands until the user has finished
// the operation.
// These commands will return an error if received in a non-interactive context.
// Selects and begins an interactive move of the given item(s).
// NOTE: Takes ownership of the active commit, if one exists:
// the move tool will push the commit when the user confirms the move,
// or roll back the commit if the user cancels the move. Keep this in
// mind if using this command in combination with commands that create
// or modify items using an explicit commit.
message InteractiveMoveItems
{
kiapi.common.types.DocumentSpecifier board = 1;
repeated kiapi.common.types.KIID items = 2;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,103 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
syntax = "proto3";
package kiapi.common.commands;
import "common/types/base_types.proto";
message GetVersion
{
}
message GetVersionResponse
{
kiapi.common.types.KiCadVersion version = 1;
}
// A command to check if the connection to KiCad is OK
message Ping
{
}
// Returns the full path to the given KiCad binary
message GetKiCadBinaryPath
{
// The short name of the binary, such as `kicad-cli` or `kicad-cli.exe`. If on Windows, an `.exe`
// extension will be assumed if not present.
string binary_name = 1;
}
message PathResponse
{
string path = 1;
}
// returns kiapi.common.types.Box2
message GetTextExtents
{
// A temporary text item to calculate the bounding box for
kiapi.common.types.Text text = 1;
}
message TextOrTextBox
{
oneof inner {
kiapi.common.types.Text text = 1;
kiapi.common.types.TextBox textbox = 2;
}
}
// Render the given text object(s) as shapes. Depending on whether the text is using
// the KiCad stroke font or a custom font, the response will be a compound shape containing
// a set of polygons or a set of segments.
message GetTextAsShapes
{
repeated TextOrTextBox text = 1;
}
message TextWithShapes
{
TextOrTextBox text = 1;
kiapi.common.types.CompoundShape shapes = 2;
}
message GetTextAsShapesResponse
{
repeated TextWithShapes text_with_shapes = 1;
}
// Return a writeable path that a plugin can use for storing persistent data such as configuration
// files, etc. This path may not yet exist; actual creation of the directory for a given plugin is
// up to the plugin itself. Files in this path will not be modified if the plugin is uninstalled or
// upgraded.
//
// Returns StringResponse
message GetPluginSettingsPath
{
// The identifier of the plugin
string identifier = 1;
}
message StringResponse
{
string response = 1;
}

View File

@ -0,0 +1,440 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Commands and responses related to manipulating editor windows
*/
syntax = "proto3";
package kiapi.common.commands;
import "google/protobuf/any.proto";
import "common/types/base_types.proto";
import "common/types/enums.proto";
// Refreshes the given frame, if that frame is open
message RefreshEditor
{
kiapi.common.types.FrameType frame = 1;
}
// Retrieves a list of open documents of the given type
message GetOpenDocuments
{
// Which type of documents to query
kiapi.common.types.DocumentType type = 1;
}
message GetOpenDocumentsResponse
{
repeated kiapi.common.types.DocumentSpecifier documents = 1;
}
message SaveDocument
{
kiapi.common.types.DocumentSpecifier document = 1;
}
// Saves the given document to a new location and opens the new copy
// Note, this is not going to be implemented anytime soon as we don't currently
// want to allow API access to changing which project is open
//message SaveDocumentAs
//{
// kiapi.common.types.DocumentSpecifier document = 1;
//
// string path = 2;
//}
message SaveOptions
{
// Overwrite destination file(s) if they exist
bool overwrite = 1;
// If the file being saved normally requires a project (for example, a board or schematic),
// this flag will cause a new project to be saved alongside the new file
bool include_project = 2;
}
// Saves the given document to a new location and does not open the new copy
message SaveCopyOfDocument
{
kiapi.common.types.DocumentSpecifier document = 1;
string path = 2;
SaveOptions options = 3;
}
message RevertDocument
{
kiapi.common.types.DocumentSpecifier document = 1;
}
/*
* Runs a TOOL_ACTION using the TOOL_MANAGER of a given frame.
* WARNING: The TOOL_ACTIONs are specifically *not* an API.
* Command names may change as code is refactored, and commands may disappear.
* This API method is provided for low-level prototyping purposes only.
*/
message RunAction
{
string action = 1; // Action name, like "eeschema.InteractiveSelection.ClearSelection"
}
enum RunActionStatus
{
RAS_UNKNOWN = 0;
RAS_OK = 1; // The action was submitted successfully.
RAS_INVALID = 2; // The action was unknown for the targeted frame.
RAS_FRAME_NOT_OPEN = 3; // The targeted frame was not open when the call was submitted.
}
/*
* NOTE: At the moment, RAS_FRAME_NOT_OPEN won't be returned as the handler is inside the frame.
*/
message RunActionResponse
{
RunActionStatus status = 1;
}
/*
* Begins a staged set of changes. Any modifications made to a document through the API after this
* call will be saved to a pending commit, and will not appear in KiCad until a matching call to
* END_COMMIT.
*/
message BeginCommit
{
}
message BeginCommitResponse
{
// Opaque identifier tracking a commit
kiapi.common.types.KIID id = 1;
}
enum CommitAction
{
CMA_UNKNOWN = 0;
CMA_COMMIT = 1; // Commit the changes to the design
CMA_DROP = 2; // Cancel this commit
}
message EndCommit
{
// The ID that was given by BeginCommit
kiapi.common.types.KIID id = 1;
// What to do with this commit
CommitAction action = 2;
// Optional message describing this changeset
string message = 3;
}
message EndCommitResponse
{
}
// Creates new items on a given document
message CreateItems
{
// Specifies which document to create on, which fields are included, etc.
kiapi.common.types.ItemHeader header = 1;
// List of items to create
repeated google.protobuf.Any items = 2;
// Items may be created on a top-level document (sheet, board, etc) or inside a container
// (symbol, footprint). If this field is not empty, it holds the ID of a symbol or footprint
// that the items should be added to. This ID must be an existing symbol (for schematic
// documents) or footprint (for board documents). If the given container does not exist or is
// not the correct item type, the CreateItems call will fail.
kiapi.common.types.KIID container = 3;
}
enum ItemStatusCode
{
ISC_UNKNOWN = 0;
ISC_OK = 1; // The item was created or updated
ISC_INVALID_TYPE = 2; // The item's type is not valid for the given document
ISC_EXISTING = 3; // The item to be created had a specified KIID and that KIID was already in use
ISC_NONEXISTENT = 4; // The item to be updated did not exist in the given document
ISC_IMMUTABLE = 5; // The item to be updated is not allowed to be modified by the API
ISC_INVALID_DATA = 7; // The item to be created does not have valid data for the given document
}
// Per-item status feedback for creation and update calls
message ItemStatus
{
ItemStatusCode code = 1;
string error_message = 2;
}
message ItemCreationResult
{
ItemStatus status = 1;
// The created version of the item, including an updated KIID as applicable
google.protobuf.Any item = 2;
}
message CreateItemsResponse
{
// Specifies which document was modified, which fields are included in created_items, etc.
kiapi.common.types.ItemHeader header = 1;
// Status of the overall request; may return IRS_OK even if no items were created
kiapi.common.types.ItemRequestStatus status = 2;
// Status of each item to be created
repeated ItemCreationResult created_items = 3;
}
message GetItems
{
// Specifies which document to query, which fields to return, etc.
kiapi.common.types.ItemHeader header = 1;
// List of one or more types of items to retreive
repeated kiapi.common.types.KiCadObjectType types = 2;
}
message GetItemsById
{
// Specifies which document to query, which fields to return, etc.
kiapi.common.types.ItemHeader header = 1;
repeated kiapi.common.types.KIID items = 2;
}
message GetItemsResponse
{
// Specifies which document was modified, which fields are included in items, etc.
kiapi.common.types.ItemHeader header = 1;
// Status of the overall request; may return IRS_OK even if no items were retrieved
kiapi.common.types.ItemRequestStatus status = 2;
repeated google.protobuf.Any items = 3;
}
// Updates items in a given document
message UpdateItems
{
// Specifies which document to modify, which fields are included, etc.
kiapi.common.types.ItemHeader header = 1;
// List of items to modify
repeated google.protobuf.Any items = 2;
}
message ItemUpdateResult
{
ItemStatus status = 1;
// The update version of the item
google.protobuf.Any item = 2;
}
message UpdateItemsResponse
{
// Specifies which document was modified, which fields are included in updated_items, etc.
kiapi.common.types.ItemHeader header = 1;
// Status of the overall request; may return IRS_OK even if no items were modified
kiapi.common.types.ItemRequestStatus status = 2;
// Status of each item to be created
repeated ItemUpdateResult updated_items = 3;
}
// Deletes items in a given document
message DeleteItems
{
// Specifies which document to modify
kiapi.common.types.ItemHeader header = 1;
// List of item KIIDs to delete
repeated kiapi.common.types.KIID item_ids = 2;
}
enum ItemDeletionStatus
{
IDS_UNKNOWN = 0;
IDS_OK = 1;
IDS_NONEXISTENT = 2; // The item did not exist in the given document
IDS_IMMUTABLE = 3; // The item is not allowed to be modified by the API
}
message ItemDeletionResult
{
kiapi.common.types.KIID id = 1;
ItemDeletionStatus status = 2;
}
message DeleteItemsResponse
{
// Specifies which document was modified, etc.
kiapi.common.types.ItemHeader header = 1;
// Status of the overall request; may return IRS_OK even if no items were deleted
kiapi.common.types.ItemRequestStatus status = 2;
// Status of each item requested to be deleted
repeated ItemDeletionResult deleted_items = 3;
}
enum BoundingBoxMode
{
BBM_UNKNOWN = 0;
BBM_ITEM_ONLY = 1;
BBM_ITEM_AND_CHILD_TEXT = 2;
}
message GetBoundingBox
{
kiapi.common.types.ItemHeader header = 1;
repeated kiapi.common.types.KIID items = 2;
// Some item types can have independently-movable text as children (e.g. footprints)
// This mode controls whether or not these are included in the box
BoundingBoxMode mode = 3;
}
message GetBoundingBoxResponse
{
repeated kiapi.common.types.KIID items = 1;
repeated kiapi.common.types.Box2 boxes = 2;
}
// Retrieves a list of items. Returns SelectionResponse
message GetSelection
{
// Specifies which document to query for selected items.
kiapi.common.types.ItemHeader header = 1;
// An optional list of types to filter on.
// If none are provided, all selected items will be returned.
repeated kiapi.common.types.KiCadObjectType types = 2;
}
// The set of currently selected items
message SelectionResponse
{
repeated google.protobuf.Any items = 1;
}
// Adds the given items to the selection. Returns SelectionResponse
message AddToSelection
{
kiapi.common.types.ItemHeader header = 1;
// The items to select
repeated kiapi.common.types.KIID items = 2;
}
// Removes the given items to the selection. Returns SelectionResponse
message RemoveFromSelection
{
kiapi.common.types.ItemHeader header = 1;
// The items to deselect
repeated kiapi.common.types.KIID items = 2;
}
// Removes all items from selection
message ClearSelection
{
kiapi.common.types.ItemHeader header = 1;
}
// Tests if a certain point falls within tolerance of an item's geometry
message HitTest
{
kiapi.common.types.ItemHeader header = 1;
kiapi.common.types.KIID id = 2;
kiapi.common.types.Vector2 position = 3;
int32 tolerance = 4;
}
enum HitTestResult
{
HTR_UNKNOWN = 0;
HTR_NO_HIT = 1;
HTR_HIT = 2;
}
message HitTestResponse
{
HitTestResult result = 1;
}
// returns common.types.TitleBlockInfo
message GetTitleBlockInfo
{
kiapi.common.types.DocumentSpecifier document = 1;
}
message SaveDocumentToString
{
kiapi.common.types.DocumentSpecifier document = 1;
}
message SavedDocumentResponse
{
kiapi.common.types.DocumentSpecifier document = 1;
string contents = 2;
}
message SaveSelectionToString
{
}
message SavedSelectionResponse
{
repeated kiapi.common.types.KIID ids = 1;
string contents = 2;
}
// Attempts to parse the given string as a s-expression formatted container with items,
// similar to how the Paste action inside the KiCad editor works. If the parse is successful,
// the items will be created and inserted into the editor.
// Returns CreateItemsResponse
message ParseAndCreateItemsFromString
{
kiapi.common.types.DocumentSpecifier document = 1;
string contents = 2;
}

View File

@ -0,0 +1,82 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
syntax = "proto3";
package kiapi.common.commands;
import "common/types/base_types.proto";
import "common/types/project_settings.proto";
message GetNetClasses
{
}
message NetClassesResponse
{
repeated kiapi.common.project.NetClass net_classes = 1;
}
message SetNetClasses
{
repeated kiapi.common.project.NetClass net_classes = 1;
// Whether to merge or replace the existing netclasses with the contents of this message
// Note that this only happens at the level of netclass name: for example, if merge_mode is set to
// MMM_MERGE, the design has netclasses ["Default", "HV"], and this message has netclasses
// ["Default", "LV"], the resulting set will be ["Default", "HV", "LV"] -- the Default netclass
// will have its properties replaced with those in this message, the "LV" netclass will be added,
// and the "HV" netclass will be left alone. If merge_mode is set to MMM_REPLACE, the "HV" class
// will be erased. Note that there must always be a "Default" netclass, so it will not be erased
// even if merge_mode is MMM_REPLACE and there is no "Default" class specified in this message.
kiapi.common.types.MapMergeMode merge_mode = 3;
}
message ExpandTextVariables
{
kiapi.common.types.DocumentSpecifier document = 1;
repeated string text = 2;
}
message ExpandTextVariablesResponse
{
repeated string text = 1;
}
// returns kiapi.common.project.TextVariables
message GetTextVariables
{
kiapi.common.types.DocumentSpecifier document = 1;
}
message SetTextVariables
{
kiapi.common.types.DocumentSpecifier document = 1;
kiapi.common.project.TextVariables variables = 2;
// Whether to merge or replace the existing text variables map with the contents of this message
kiapi.common.types.MapMergeMode merge_mode = 3;
}

View File

@ -0,0 +1,92 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
syntax = "proto3";
package kiapi.common;
import "google/protobuf/any.proto";
enum ApiStatusCode
{
AS_UNKNOWN = 0;
AS_OK = 1; // Request succeeded
AS_TIMEOUT = 2; // Request timed out
AS_BAD_REQUEST = 3; // The request had invalid parameters or otherwise was illegal
AS_NOT_READY = 4; // KiCad has recently started and cannot handle API requests yet
AS_UNHANDLED = 5; // The request was not handled by KiCad
AS_TOKEN_MISMATCH = 6; // The kicad_token in the request didn't match this KiCad's token
AS_BUSY = 7; // KiCad is busy performing an operation and can't accept API commands
AS_UNIMPLEMENTED = 8; // The requested API call has not yet been implemented
}
/*
* For future expansion: any header fields that should be sent with a request
*/
message ApiRequestHeader
{
// An opaque string identifying a running instance of KiCad. If this is set to a non-empty
// string in an API request, KiCad will reject the request if the value doesn't match its own
// token. This can be used to let API clients make sure they are still talking to the same
// instance of KiCad if they are long-running.
string kicad_token = 1;
// A string identifying an API client. Should be set by the client to a value that is unique
// to a specific instance of a client, for example the package name of the client plus its
// process ID or a random string, e.g. "com.github.me.my_awesome_plugin-73951". The main purpose
// of this name is to identify the client in debug logs.
string client_name = 2;
}
/*
* The top-level envelope container for an API request (message from a client to the KiCad API server)
*/
message ApiRequest
{
ApiRequestHeader header = 1;
google.protobuf.Any message = 2;
}
/*
* For future expansion: any header fields that should be sent with a response
*/
message ApiResponseHeader
{
/// An opaque string identifying a running instance of KiCad.
string kicad_token = 1;
}
message ApiResponse
{
ApiResponseHeader header = 1;
ApiResponseStatus status = 2;
google.protobuf.Any message = 3;
}
message ApiResponseStatus
{
/// A code describing the category of error (or AS_OK if no error)
ApiStatusCode status = 1;
/// A human-readable description of the error, if any
string error_message = 2;
}

View File

@ -0,0 +1,482 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* base_types.proto
* Includes types used in many parts of the API
*/
syntax = "proto3";
package kiapi.common.types;
import "google/protobuf/field_mask.proto";
import "common/types/enums.proto";
enum CommandStatus
{
CS_UNKNOWN = 0;
CS_OK = 1; // Command succeeded
CS_FAILED = 2; // Command failed
}
message CommandStatusResponse
{
CommandStatus status = 1;
}
/**
* Describes a particular version of KiCad
*/
message KiCadVersion
{
uint32 major = 1;
uint32 minor = 2;
uint32 patch = 3;
// Full identifier string, potentially containing git hashes, packager-added info, etc.
string full_version = 4;
}
/**
* Some commands are specific to a KiCad window (frame). This list contains all addressable frames.
*/
enum FrameType
{
FT_UNKNOWN = 0;
FT_PROJECT_MANAGER = 1;
FT_SCHEMATIC_EDITOR = 2;
FT_PCB_EDITOR = 3;
FT_SPICE_SIMULATOR = 4;
FT_SYMBOL_EDITOR = 5;
FT_FOOTPRINT_EDITOR = 6;
FT_DRAWING_SHEET_EDITOR = 7;
}
/**
* Describes a KIID, or UUID of an object in a KiCad editor model.
*/
message KIID
{
// The KIID's value in standard UUID format, stored as a string for easy portability
string value = 1;
}
/**
* Identifier for the type of document being targeted by a request
*/
enum DocumentType
{
DOCTYPE_UNKNOWN = 0;
DOCTYPE_SCHEMATIC = 1;
DOCTYPE_SYMBOL = 2;
DOCTYPE_PCB = 3;
DOCTYPE_FOOTPRINT = 4;
DOCTYPE_DRAWING_SHEET = 5;
DOCTYPE_PROJECT = 6;
}
/**
* Describes a KiCad LIB_ID; a unique identifier for a loaded symbol or footprint
*/
message LibraryIdentifier
{
// The library portion of the LIB_ID
string library_nickname = 1;
// The symbol or footprint name
string entry_name = 2;
}
/**
* Describes a unique sheet in a schematic
*/
message SheetPath
{
// The canonical path to the sheet. The first KIID will be the root sheet, etc.
repeated KIID path = 1;
// The path converted to a human readable form such as "/", "/child", or "/child/grandchild"
string path_human_readable = 2;
}
/**
* Describes a KiCad project
*/
message ProjectSpecifier
{
// The name of the project (without the kicad_pro extension)
string name = 1;
// The path to the project directory
string path = 2;
}
/**
* Describes a document that will be the target of a request
*/
message DocumentSpecifier
{
DocumentType type = 1;
oneof identifier
{
// If type == DT_SYMBOL or DT_FOOTPRINT, identifies a certain library entry
LibraryIdentifier lib_id = 2;
// If type == DT_SCHEMATIC, identifies a sheet with a given path
SheetPath sheet_path = 3;
// If type == DT_PCB, identifies a PCB with a given filename, e.g. "board.kicad_pcb"
string board_filename = 4;
}
ProjectSpecifier project = 5;
}
/**
* This header is included in requests and responses about item(s) in a document
*/
message ItemHeader
{
// Which document is this request targeting?
DocumentSpecifier document = 1;
// Which container within the document is this request targeting?
// If container is omitted or empty, the document is used as the container.
KIID container = 2;
// Which fields on the item(s) are included with this request or response
google.protobuf.FieldMask field_mask = 3;
}
/**
* Status of a request that included an ItemHeader
*/
enum ItemRequestStatus
{
IRS_UNKNOWN = 0;
IRS_OK = 1;
IRS_DOCUMENT_NOT_FOUND = 2; // The given document is not open in KiCad
IRS_FIELD_MASK_INVALID = 3; // The given field_mask contains invalid specifiers
}
// Describes a point or distance in 2D space. All coordinates are in nanometers.
message Vector2
{
int64 x_nm = 1;
int64 y_nm = 2;
}
// Describes a point or distance in 3D space. All coordinates are in nanometers.
message Vector3
{
int64 x_nm = 1;
int64 y_nm = 2;
int64 z_nm = 3;
}
message Vector3D
{
double x_nm = 1;
double y_nm = 2;
double z_nm = 3;
}
message Box2
{
kiapi.common.types.Vector2 position = 1;
kiapi.common.types.Vector2 size = 2;
}
// Describes a quantity of distance (size, length, etc). All coordinates are in nanometers.
message Distance
{
int64 value_nm = 1;
}
// Corresponds to EDA_ANGLE, where the underlying storage is degrees
message Angle
{
double value_degrees = 1;
}
// Represents a value from 0.0 to 1.0
message Ratio
{
double value = 1;
}
// Represents a time delay in attoseconds. Since 10.0.0.
message Time
{
int64 value_as = 1;
}
// Corresponds to COLOR4D. Each color channel is a double from 0.0 to 1.0.
message Color
{
double r = 1;
double g = 2;
double b = 3;
double a = 4;
}
// The formulation of arc that is used in KiCad core geometry code.
// Start, midpoint (on the arc) and end are stored. Angle, center point, etc are calculated.
message ArcStartMidEnd
{
Vector2 start = 1;
Vector2 mid = 2;
Vector2 end = 3;
}
message PolyLineNode
{
oneof geometry {
Vector2 point = 1;
ArcStartMidEnd arc = 2;
}
}
// Corresponds to class SHAPE_LINE_CHAIN: A closed or open polyline that can include arcs.
// For non-arc cases, each node is a point along the line. An implicit line segment exists
// between the last and first node if closed is true. When arcs are present, the arc start and
// end points are not duplicated by point nodes (meaning, for example, a rectangle with rounded
// corners could be represented with four arc nodes and no point nodes).
message PolyLine
{
repeated PolyLineNode nodes = 1;
bool closed = 2;
}
message PolygonWithHoles
{
PolyLine outline = 1;
repeated PolyLine holes = 2;
}
// Corresponds to SHAPE_POLY_SET: a set of polygons or polylines
message PolySet
{
repeated PolygonWithHoles polygons = 1;
}
// Describes whether or not an item is locked for editing or movement
enum LockedState
{
LS_UNKNOWN = 0;
LS_UNLOCKED = 1;
LS_LOCKED = 2;
}
message TextAttributes
{
string font_name = 1;
HorizontalAlignment horizontal_alignment = 2;
VerticalAlignment vertical_alignment = 3;
kiapi.common.types.Angle angle = 4;
double line_spacing = 5;
kiapi.common.types.Distance stroke_width = 6;
bool italic = 7;
bool bold = 8;
bool underlined = 9;
// Deprecated since 9.0.1 (text items are now always visible, only Fields can be hidden)
bool visible = 10;
bool mirrored = 11;
bool multiline = 12;
bool keep_upright = 13;
kiapi.common.types.Vector2 size = 14;
}
message Text
{
// Reserved for future use; base text objects don't have IDs right now
// kiapi.common.types.KIID id = 1;
kiapi.common.types.Vector2 position = 2;
kiapi.common.types.TextAttributes attributes = 3;
// Reserved for future use; base objects don't support locking right now
//kiapi.common.types.LockedState locked = 4;
string text = 5;
string hyperlink = 6;
}
message TextBox
{
kiapi.common.types.Vector2 top_left = 2;
kiapi.common.types.Vector2 bottom_right = 3;
kiapi.common.types.TextAttributes attributes = 4;
// Reserved for future use; base objects don't support locking right now
//kiapi.common.types.LockedState locked = 5;
string text = 6;
}
message StrokeAttributes
{
Distance width = 1;
StrokeLineStyle style = 2;
Color color = 3;
}
enum GraphicFillType
{
GFT_UNKNOWN = 0;
GFT_UNFILLED = 1;
GFT_FILLED = 2;
}
message GraphicFillAttributes
{
GraphicFillType fill_type = 1;
// Color of the fill (not used in board and footprints)
Color color = 2;
}
message GraphicAttributes
{
StrokeAttributes stroke = 1;
GraphicFillAttributes fill = 2;
}
message GraphicSegmentAttributes
{
kiapi.common.types.Vector2 start = 1;
kiapi.common.types.Vector2 end = 2;
}
message GraphicRectangleAttributes
{
kiapi.common.types.Vector2 top_left = 1;
kiapi.common.types.Vector2 bottom_right = 2;
kiapi.common.types.Distance corner_radius = 3;
}
message GraphicArcAttributes
{
kiapi.common.types.Vector2 start = 1;
kiapi.common.types.Vector2 mid = 2;
kiapi.common.types.Vector2 end = 3;
}
message GraphicCircleAttributes
{
kiapi.common.types.Vector2 center = 1;
// A point on the radius of the circle. This is stored instead of just a radius so that the point
// by which the user can adjust the circle radius is persisted.
kiapi.common.types.Vector2 radius_point = 2;
}
message GraphicBezierAttributes
{
kiapi.common.types.Vector2 start = 1;
kiapi.common.types.Vector2 control1 = 2;
kiapi.common.types.Vector2 control2 = 3;
kiapi.common.types.Vector2 end = 4;
}
message GraphicShape
{
// Reserved for future use; base EDA_SHAPE doesn't have an ID or locked state right now
// KIID id = 1;
// LockedState locked = 2;
GraphicAttributes attributes = 3;
oneof geometry {
GraphicSegmentAttributes segment = 4;
GraphicRectangleAttributes rectangle = 5;
GraphicArcAttributes arc = 6;
GraphicCircleAttributes circle = 7;
PolySet polygon = 8;
GraphicBezierAttributes bezier = 9;
}
}
// A SHAPE_COMPOUND in KiCad
message CompoundShape
{
repeated GraphicShape shapes = 1;
}
// The text strings that can be set in a drawing sheet for the title block
message TitleBlockInfo
{
string title = 1;
string date = 2;
string revision = 3;
string company = 4;
// Note: not a repeated string; there can be gaps and the UI limits the count to 9
string comment1 = 5;
string comment2 = 6;
string comment3 = 7;
string comment4 = 8;
string comment5 = 9;
string comment6 = 10;
string comment7 = 11;
string comment8 = 12;
string comment9 = 13;
}
enum AxisAlignment
{
AA_UNKNOWN = 0;
AA_X_AXIS = 1;
AA_Y_AXIS = 2;
}
enum MapMergeMode
{
MMM_UNKNOWN = 0;
// The existing map will be merged with the incoming map; keys that are not present in the
// incoming map will be preserved with their original values
MMM_MERGE = 1;
// The existing map will be cleared and replaced with the incoming map
MMM_REPLACE = 2;
}
enum ElectricalPinType
{
EPT_UNKNOWN = 0;
EPT_INPUT = 1;
EPT_OUTPUT = 2;
EPT_BIDIRECTIONAL = 3;
EPT_TRISTATE = 4;
EPT_PASSIVE = 5;
// A free pin is not internally connected and may connect to any net (route-through)
EPT_FREE = 6;
EPT_UNSPECIFIED = 7;
EPT_POWER_INPUT = 8;
EPT_POWER_OUTPUT = 9;
EPT_OPEN_COLLECTOR = 10;
EPT_OPEN_EMITTER = 11;
// A no-connect pin should not be connected to any net
EPT_NO_CONNECT = 12;
}

View File

@ -0,0 +1,122 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* enums.proto
* Includes protobuf versions of common KiCad enums
*/
syntax = "proto3";
package kiapi.common.types;
// The set of object types (from KICAD_T) that are exposed to the API.
enum KiCadObjectType
{
KOT_UNKNOWN = 0;
KOT_PCB_FOOTPRINT = 1;
KOT_PCB_PAD = 2;
KOT_PCB_SHAPE = 3;
KOT_PCB_REFERENCE_IMAGE = 4;
KOT_PCB_FIELD = 5;
KOT_PCB_GENERATOR = 6;
KOT_PCB_TEXT = 7;
KOT_PCB_TEXTBOX = 8;
KOT_PCB_TABLE = 9;
KOT_PCB_TABLECELL = 10;
KOT_PCB_TRACE = 11;
KOT_PCB_VIA = 12;
KOT_PCB_ARC = 13;
KOT_PCB_MARKER = 14;
KOT_PCB_DIMENSION = 15;
KOT_PCB_ZONE = 16;
KOT_PCB_GROUP = 17;
KOT_SCH_MARKER = 18;
KOT_SCH_JUNCTION = 19;
KOT_SCH_NO_CONNECT = 20;
KOT_SCH_BUS_WIRE_ENTRY = 21;
KOT_SCH_BUS_BUS_ENTRY = 22;
KOT_SCH_LINE = 23;
KOT_SCH_SHAPE = 24;
KOT_SCH_BITMAP = 25;
KOT_SCH_TEXTBOX = 26;
KOT_SCH_TEXT = 27;
KOT_SCH_TABLE = 28;
KOT_SCH_TABLECELL = 29;
KOT_SCH_LABEL = 30;
KOT_SCH_GLOBAL_LABEL = 31;
KOT_SCH_HIER_LABEL = 32;
KOT_SCH_DIRECTIVE_LABEL = 33;
KOT_SCH_FIELD = 34;
KOT_SCH_SYMBOL = 35;
KOT_SCH_SHEET_PIN = 36;
KOT_SCH_SHEET = 37;
KOT_SCH_PIN = 38;
KOT_LIB_SYMBOL = 39;
// KOT_LIB_SHAPE = 40;
// KOT_LIB_TEXT = 41;
// KOT_LIB_TEXTBOX = 42;
// KOT_LIB_PIN = 43;
// KOT_LIB_FIELD = 44;
KOT_WSG_LINE = 45;
KOT_WSG_RECT = 46;
KOT_WSG_POLY = 47;
KOT_WSG_TEXT = 48;
KOT_WSG_BITMAP = 49;
KOT_WSG_PAGE = 50;
KOT_SCH_GROUP = 51;
KOT_PCB_BARCODE = 52;
}
// Mapped to GR_TEXT_H_ALIGN_T
enum HorizontalAlignment
{
HA_UNKNOWN = 0;
HA_LEFT = 1;
HA_CENTER = 2;
HA_RIGHT = 3;
HA_INDETERMINATE = 4;
}
// Mapped to GR_TEXT_V_ALIGN_T
enum VerticalAlignment
{
VA_UNKNOWN = 0;
VA_TOP = 1;
VA_CENTER = 2;
VA_BOTTOM = 3;
VA_INDETERMINATE = 4;
}
// Mapped to LINE_STYLE
enum StrokeLineStyle
{
SLS_UNKNOWN = 0;
SLS_DEFAULT = 1;
SLS_SOLID = 2;
SLS_DASH = 3;
SLS_DOT = 4;
SLS_DASHDOT = 5;
SLS_DASHDOTDOT = 6;
}

View File

@ -0,0 +1,94 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* project_settings.proto
* Messages that describes project settings shared between schematics and boards
*/
syntax = "proto3";
package kiapi.common.project;
import "common/types/base_types.proto";
import "common/types/enums.proto";
import "board/board_types.proto";
message NetClassBoardSettings
{
optional kiapi.common.types.Distance clearance = 1;
optional kiapi.common.types.Distance track_width = 2;
optional kiapi.common.types.Distance diff_pair_track_width = 3;
optional kiapi.common.types.Distance diff_pair_gap = 4;
optional kiapi.common.types.Distance diff_pair_via_gap = 5;
// The default padstack to use for vias belonging to this netclass
// Currently KiCad only supports specifying the drill diameter and annular size on all layers for
// netclass via stacks. Complex padstacks and other via features cannot be specified here.
optional kiapi.board.types.PadStack via_stack = 6;
// The default padstack to use for microvias belonging to this netclass
// Currently KiCad only supports specifying the drill diameter and annular size on all layers for
// netclass via stacks. Complex padstacks and other via features cannot be specified here.
optional kiapi.board.types.PadStack microvia_stack = 7;
optional kiapi.common.types.Color color = 8;
// Since 10.0.0
optional string tuning_profile = 9;
}
message NetClassSchematicSettings
{
optional kiapi.common.types.Distance wire_width = 1;
optional kiapi.common.types.Distance bus_width = 2;
optional kiapi.common.types.Color color = 3;
optional kiapi.common.types.StrokeLineStyle line_style = 4;
}
enum NetClassType
{
NCT_UNKNOWN = 0;
// An explicitly-defined netclass, created by the user and saved in the project file
NCT_EXPLICIT = 1;
// An implicit (effective) netclass, made up of multiple explicit netclasses
NCT_IMPLICIT = 2;
}
message NetClass
{
// The name of the netclass (the literal string "Default" for the default netclass)
// May be empty for composite netclasses
string name = 1;
optional int32 priority = 2;
optional NetClassBoardSettings board = 3;
optional NetClassSchematicSettings schematic = 4;
NetClassType type = 5;
// If this is a composite netclass, a list of the names of the "real" netclasses that make it up
repeated string constituents = 6;
}
message TextVariables
{
map<string, string> variables = 1;
}

View File

@ -0,0 +1,24 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
syntax = "proto3";
package kiapi.schematic.types;

View File

@ -0,0 +1,75 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
syntax = "proto3";
package kiapi.schematic.types;
import "common/types/base_types.proto";
enum SchematicLayer
{
SL_UNKNOWN = 0;
}
/// Represents a schematic line segment, which may be a wire, bus, or graphical line
message Line
{
kiapi.common.types.KIID id = 1;
kiapi.common.types.Vector2 start = 2;
kiapi.common.types.Vector2 end = 3;
/**
* One of: LAYER_BUS, LAYER_WIRE, LAYER_NOTES
*/
SchematicLayer layer = 4;
}
message Text
{
kiapi.common.types.Text text = 1;
}
message LocalLabel
{
kiapi.common.types.KIID id = 1;
kiapi.common.types.Vector2 position = 2;
Text text = 3;
}
message GlobalLabel
{
kiapi.common.types.KIID id = 1;
kiapi.common.types.Vector2 position = 2;
Text text = 3;
}
message HierarchicalLabel
{
kiapi.common.types.KIID id = 1;
kiapi.common.types.Vector2 position = 2;
Text text = 3;
}
message DirectiveLabel
{
kiapi.common.types.KIID id = 1;
kiapi.common.types.Vector2 position = 2;
Text text = 3;
}

22
src/blocking.rs Normal file
View File

@ -0,0 +1,22 @@
use crate::client::KiCadClient;
use crate::error::KiCadError;
#[derive(Clone, Debug)]
pub struct KiCadClientBlocking {
inner: KiCadClient,
}
impl KiCadClientBlocking {
pub fn connect() -> Result<Self, KiCadError> {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.map_err(|err| KiCadError::Connection(err.to_string()))?;
let inner = runtime.block_on(KiCadClient::connect())?;
Ok(Self { inner })
}
pub fn inner(&self) -> &KiCadClient {
&self.inner
}
}

99
src/client.rs Normal file
View File

@ -0,0 +1,99 @@
use std::time::Duration;
use crate::error::KiCadError;
#[derive(Clone, Debug)]
pub struct KiCadClient {
config: ClientConfig,
}
#[derive(Clone, Debug)]
struct ClientConfig {
timeout: Duration,
socket_path: Option<String>,
token: Option<String>,
client_name: Option<String>,
}
#[derive(Clone, Debug)]
pub struct ClientBuilder {
config: ClientConfig,
}
impl ClientBuilder {
pub fn new() -> Self {
Self {
config: ClientConfig {
timeout: Duration::from_millis(3_000),
socket_path: None,
token: None,
client_name: None,
},
}
}
pub fn timeout(mut self, timeout: Duration) -> Self {
self.config.timeout = timeout;
self
}
pub fn socket_path(mut self, socket_path: impl Into<String>) -> Self {
self.config.socket_path = Some(socket_path.into());
self
}
pub fn token(mut self, token: impl Into<String>) -> Self {
self.config.token = Some(token.into());
self
}
pub fn client_name(mut self, client_name: impl Into<String>) -> Self {
self.config.client_name = Some(client_name.into());
self
}
pub async fn connect(self) -> Result<KiCadClient, KiCadError> {
Ok(KiCadClient {
config: self.config,
})
}
}
impl Default for ClientBuilder {
fn default() -> Self {
Self::new()
}
}
impl KiCadClient {
pub fn builder() -> ClientBuilder {
ClientBuilder::new()
}
pub async fn connect() -> Result<Self, KiCadError> {
ClientBuilder::new().connect().await
}
pub fn timeout(&self) -> Duration {
self.config.timeout
}
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use super::ClientBuilder;
#[tokio::test]
async fn builder_overrides_timeout() {
let timeout = Duration::from_secs(9);
let client = ClientBuilder::new()
.timeout(timeout)
.connect()
.await
.expect("builder should connect in baseline scaffold");
assert_eq!(client.timeout(), timeout);
}
}

2
src/commands/base.rs Normal file
View File

@ -0,0 +1,2 @@
#[derive(Debug, Default)]
pub struct BaseCommands;

2
src/commands/board.rs Normal file
View File

@ -0,0 +1,2 @@
#[derive(Debug, Default)]
pub struct BoardCommands;

2
src/commands/editor.rs Normal file
View File

@ -0,0 +1,2 @@
#[derive(Debug, Default)]
pub struct EditorCommands;

4
src/commands/mod.rs Normal file
View File

@ -0,0 +1,4 @@
pub mod base;
pub mod board;
pub mod editor;
pub mod project;

2
src/commands/project.rs Normal file
View File

@ -0,0 +1,2 @@
#[derive(Debug, Default)]
pub struct ProjectCommands;

2
src/envelope.rs Normal file
View File

@ -0,0 +1,2 @@
#[derive(Debug, Default)]
pub struct Envelope;

13
src/error.rs Normal file
View File

@ -0,0 +1,13 @@
use thiserror::Error;
#[derive(Debug, Error)]
pub enum KiCadError {
#[error("connection failed: {0}")]
Connection(String),
#[error("invalid configuration: {0}")]
Config(String),
#[error("transport error: {0}")]
Transport(String),
#[error("protocol error: {0}")]
Protocol(String),
}

21
src/lib.rs Normal file
View File

@ -0,0 +1,21 @@
//! Async-first Rust bindings for the KiCad IPC API.
//!
//! This crate is intentionally layered:
//! - transport
//! - envelope
//! - command builders
//! - high-level client
pub mod client;
pub mod envelope;
pub mod error;
pub mod model;
pub mod transport;
pub mod commands;
#[cfg(feature = "blocking")]
pub mod blocking;
pub use crate::client::{ClientBuilder, KiCadClient};
pub use crate::error::KiCadError;

4
src/model/board.rs Normal file
View File

@ -0,0 +1,4 @@
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BoardDocument {
pub board_filename: String,
}

7
src/model/common.rs Normal file
View File

@ -0,0 +1,7 @@
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VersionInfo {
pub major: u32,
pub minor: u32,
pub patch: u32,
pub full_version: String,
}

2
src/model/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod board;
pub mod common;

2
src/transport.rs Normal file
View File

@ -0,0 +1,2 @@
#[derive(Debug, Default)]
pub struct Transport;