feat(client): add SetBoardEnabledLayers API and CLI command
This commit is contained in:
parent
080d5cf537
commit
e147186fbf
|
|
@ -41,9 +41,9 @@ Legend:
|
||||||
| Common (base) | 6 | 4 | 67% |
|
| Common (base) | 6 | 4 | 67% |
|
||||||
| Common editor/document | 23 | 12 | 52% |
|
| Common editor/document | 23 | 12 | 52% |
|
||||||
| Project manager | 5 | 3 | 60% |
|
| Project manager | 5 | 3 | 60% |
|
||||||
| Board editor (PCB) | 22 | 16 | 73% |
|
| Board editor (PCB) | 22 | 17 | 77% |
|
||||||
| Schematic editor (dedicated proto commands) | 0 | 0 | n/a |
|
| Schematic editor (dedicated proto commands) | 0 | 0 | n/a |
|
||||||
| **Total** | **56** | **35** | **63%** |
|
| **Total** | **56** | **36** | **64%** |
|
||||||
|
|
||||||
### Common (base)
|
### Common (base)
|
||||||
|
|
||||||
|
|
@ -101,7 +101,7 @@ Legend:
|
||||||
| `GetBoardStackup` | Implemented | `KiCadClient::get_board_stackup_raw`, `KiCadClient::get_board_stackup` |
|
| `GetBoardStackup` | Implemented | `KiCadClient::get_board_stackup_raw`, `KiCadClient::get_board_stackup` |
|
||||||
| `UpdateBoardStackup` | Not yet | - |
|
| `UpdateBoardStackup` | Not yet | - |
|
||||||
| `GetBoardEnabledLayers` | Implemented | `KiCadClient::get_board_enabled_layers` |
|
| `GetBoardEnabledLayers` | Implemented | `KiCadClient::get_board_enabled_layers` |
|
||||||
| `SetBoardEnabledLayers` | Not yet | - |
|
| `SetBoardEnabledLayers` | Implemented | `KiCadClient::set_board_enabled_layers` |
|
||||||
| `GetGraphicsDefaults` | Implemented | `KiCadClient::get_graphics_defaults_raw`, `KiCadClient::get_graphics_defaults` |
|
| `GetGraphicsDefaults` | Implemented | `KiCadClient::get_graphics_defaults_raw`, `KiCadClient::get_graphics_defaults` |
|
||||||
| `GetBoardOrigin` | Implemented | `KiCadClient::get_board_origin` |
|
| `GetBoardOrigin` | Implemented | `KiCadClient::get_board_origin` |
|
||||||
| `SetBoardOrigin` | Implemented | `KiCadClient::set_board_origin` |
|
| `SetBoardOrigin` | Implemented | `KiCadClient::set_board_origin` |
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,12 @@ List enabled board layers:
|
||||||
cargo run --bin kicad-ipc-cli -- enabled-layers
|
cargo run --bin kicad-ipc-cli -- enabled-layers
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Set enabled board layers:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run --bin kicad-ipc-cli -- set-enabled-layers --copper-layer-count 2 --layer-id 47 --layer-id 52
|
||||||
|
```
|
||||||
|
|
||||||
Show active layer:
|
Show active layer:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ const CMD_REFRESH_EDITOR: &str = "kiapi.common.commands.RefreshEditor";
|
||||||
const CMD_GET_OPEN_DOCUMENTS: &str = "kiapi.common.commands.GetOpenDocuments";
|
const CMD_GET_OPEN_DOCUMENTS: &str = "kiapi.common.commands.GetOpenDocuments";
|
||||||
const CMD_GET_NETS: &str = "kiapi.board.commands.GetNets";
|
const CMD_GET_NETS: &str = "kiapi.board.commands.GetNets";
|
||||||
const CMD_GET_BOARD_ENABLED_LAYERS: &str = "kiapi.board.commands.GetBoardEnabledLayers";
|
const CMD_GET_BOARD_ENABLED_LAYERS: &str = "kiapi.board.commands.GetBoardEnabledLayers";
|
||||||
|
const CMD_SET_BOARD_ENABLED_LAYERS: &str = "kiapi.board.commands.SetBoardEnabledLayers";
|
||||||
const CMD_GET_ACTIVE_LAYER: &str = "kiapi.board.commands.GetActiveLayer";
|
const CMD_GET_ACTIVE_LAYER: &str = "kiapi.board.commands.GetActiveLayer";
|
||||||
const CMD_SET_ACTIVE_LAYER: &str = "kiapi.board.commands.SetActiveLayer";
|
const CMD_SET_ACTIVE_LAYER: &str = "kiapi.board.commands.SetActiveLayer";
|
||||||
const CMD_GET_VISIBLE_LAYERS: &str = "kiapi.board.commands.GetVisibleLayers";
|
const CMD_GET_VISIBLE_LAYERS: &str = "kiapi.board.commands.GetVisibleLayers";
|
||||||
|
|
@ -564,10 +565,28 @@ impl KiCadClient {
|
||||||
let payload: board_commands::BoardEnabledLayersResponse =
|
let payload: board_commands::BoardEnabledLayersResponse =
|
||||||
envelope::unpack_any(&response, RES_GET_BOARD_ENABLED_LAYERS)?;
|
envelope::unpack_any(&response, RES_GET_BOARD_ENABLED_LAYERS)?;
|
||||||
|
|
||||||
Ok(BoardEnabledLayers {
|
Ok(map_board_enabled_layers_response(payload))
|
||||||
copper_layer_count: payload.copper_layer_count,
|
}
|
||||||
layers: payload.layers.into_iter().map(layer_to_model).collect(),
|
|
||||||
})
|
pub async fn set_board_enabled_layers(
|
||||||
|
&self,
|
||||||
|
copper_layer_count: u32,
|
||||||
|
layer_ids: Vec<i32>,
|
||||||
|
) -> Result<BoardEnabledLayers, KiCadError> {
|
||||||
|
let board = self.current_board_document_proto().await?;
|
||||||
|
let command = board_commands::SetBoardEnabledLayers {
|
||||||
|
board: Some(board),
|
||||||
|
copper_layer_count,
|
||||||
|
layers: layer_ids,
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = self
|
||||||
|
.send_command(envelope::pack_any(&command, CMD_SET_BOARD_ENABLED_LAYERS))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let payload: board_commands::BoardEnabledLayersResponse =
|
||||||
|
envelope::unpack_any(&response, RES_GET_BOARD_ENABLED_LAYERS)?;
|
||||||
|
Ok(map_board_enabled_layers_response(payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_active_layer(&self) -> Result<BoardLayerInfo, KiCadError> {
|
pub async fn get_active_layer(&self) -> Result<BoardLayerInfo, KiCadError> {
|
||||||
|
|
@ -1618,6 +1637,15 @@ fn layer_to_model(layer_id: i32) -> BoardLayerInfo {
|
||||||
BoardLayerInfo { id: layer_id, name }
|
BoardLayerInfo { id: layer_id, name }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn map_board_enabled_layers_response(
|
||||||
|
payload: board_commands::BoardEnabledLayersResponse,
|
||||||
|
) -> BoardEnabledLayers {
|
||||||
|
BoardEnabledLayers {
|
||||||
|
copper_layer_count: payload.copper_layer_count,
|
||||||
|
layers: payload.layers.into_iter().map(layer_to_model).collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn board_origin_kind_to_proto(kind: BoardOriginKind) -> i32 {
|
fn board_origin_kind_to_proto(kind: BoardOriginKind) -> i32 {
|
||||||
match kind {
|
match kind {
|
||||||
BoardOriginKind::Grid => board_commands::BoardOriginType::BotGrid as i32,
|
BoardOriginKind::Grid => board_commands::BoardOriginType::BotGrid as i32,
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,10 @@ enum Command {
|
||||||
},
|
},
|
||||||
Nets,
|
Nets,
|
||||||
EnabledLayers,
|
EnabledLayers,
|
||||||
|
SetEnabledLayers {
|
||||||
|
copper_layer_count: u32,
|
||||||
|
layer_ids: Vec<i32>,
|
||||||
|
},
|
||||||
ActiveLayer,
|
ActiveLayer,
|
||||||
SetActiveLayer {
|
SetActiveLayer {
|
||||||
layer_id: i32,
|
layer_id: i32,
|
||||||
|
|
@ -310,6 +314,18 @@ async fn run() -> Result<(), KiCadError> {
|
||||||
println!("layer_id={} layer_name={}", layer.id, layer.name);
|
println!("layer_id={} layer_name={}", layer.id, layer.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Command::SetEnabledLayers {
|
||||||
|
copper_layer_count,
|
||||||
|
layer_ids,
|
||||||
|
} => {
|
||||||
|
let enabled = client
|
||||||
|
.set_board_enabled_layers(copper_layer_count, layer_ids)
|
||||||
|
.await?;
|
||||||
|
println!("copper_layer_count={}", enabled.copper_layer_count);
|
||||||
|
for layer in enabled.layers {
|
||||||
|
println!("layer_id={} layer_name={}", layer.id, layer.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
Command::ActiveLayer => {
|
Command::ActiveLayer => {
|
||||||
let layer = client.get_active_layer().await?;
|
let layer = client.get_active_layer().await?;
|
||||||
println!(
|
println!(
|
||||||
|
|
@ -808,6 +824,49 @@ fn parse_args_from(mut args: Vec<String>) -> Result<(CliConfig, Command), KiCadE
|
||||||
}
|
}
|
||||||
"nets" => Command::Nets,
|
"nets" => Command::Nets,
|
||||||
"enabled-layers" => Command::EnabledLayers,
|
"enabled-layers" => Command::EnabledLayers,
|
||||||
|
"set-enabled-layers" => {
|
||||||
|
let mut copper_layer_count = None;
|
||||||
|
let mut layer_ids = Vec::new();
|
||||||
|
let mut i = 1;
|
||||||
|
while i < args.len() {
|
||||||
|
match args[i].as_str() {
|
||||||
|
"--copper-layer-count" => {
|
||||||
|
let value = args.get(i + 1).ok_or_else(|| KiCadError::Config {
|
||||||
|
reason: "missing value for set-enabled-layers --copper-layer-count"
|
||||||
|
.to_string(),
|
||||||
|
})?;
|
||||||
|
copper_layer_count =
|
||||||
|
Some(value.parse::<u32>().map_err(|err| KiCadError::Config {
|
||||||
|
reason: format!(
|
||||||
|
"invalid set-enabled-layers --copper-layer-count `{value}`: {err}"
|
||||||
|
),
|
||||||
|
})?);
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
"--layer-id" => {
|
||||||
|
let value = args.get(i + 1).ok_or_else(|| KiCadError::Config {
|
||||||
|
reason: "missing value for set-enabled-layers --layer-id".to_string(),
|
||||||
|
})?;
|
||||||
|
layer_ids.push(value.parse::<i32>().map_err(|err| KiCadError::Config {
|
||||||
|
reason: format!(
|
||||||
|
"invalid set-enabled-layers --layer-id `{value}`: {err}"
|
||||||
|
),
|
||||||
|
})?);
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Command::SetEnabledLayers {
|
||||||
|
copper_layer_count: copper_layer_count.ok_or_else(|| KiCadError::Config {
|
||||||
|
reason: "set-enabled-layers requires `--copper-layer-count <u32>`".to_string(),
|
||||||
|
})?,
|
||||||
|
layer_ids,
|
||||||
|
}
|
||||||
|
}
|
||||||
"active-layer" => Command::ActiveLayer,
|
"active-layer" => Command::ActiveLayer,
|
||||||
"set-active-layer" => {
|
"set-active-layer" => {
|
||||||
let mut layer_id = None;
|
let mut layer_id = None;
|
||||||
|
|
@ -1299,7 +1358,7 @@ fn default_config() -> CliConfig {
|
||||||
|
|
||||||
fn print_help() {
|
fn print_help() {
|
||||||
println!(
|
println!(
|
||||||
"kicad-ipc-cli\n\nUSAGE:\n cargo run --bin kicad-ipc-cli -- [--socket URI] [--token TOKEN] [--client-name NAME] [--timeout-ms N] <command> [command options]\n\nCOMMANDS:\n ping Check IPC connectivity\n version Fetch KiCad version\n open-docs [--type <type>] List open docs (default type: pcb)\n project-path Get current project path from open PCB docs\n board-open Exit non-zero if no PCB doc is open\n net-classes List project netclass definitions\n text-variables List text variables for current board document\n expand-text-variables Expand variables in provided text values\n Options: --text <value> (repeatable)\n text-extents Measure text bounding box\n Options: --text <value>\n text-as-shapes Convert text to rendered shapes\n Options: --text <value> (repeatable)\n nets List board nets (requires one open PCB)\n netlist-pads Emit pad-level netlist data (with footprint context)\n items-by-id --id <uuid> ... Show parsed details for specific item IDs\n item-bbox --id <uuid> ... Show bounding boxes for item IDs\n hit-test --id <uuid> --x-nm <x> --y-nm <y> [--tolerance-nm <n>]\n Hit-test one item at a point\n types-pcb List PCB KiCad object type IDs from proto enum\n items-raw --type-id <id> ... Dump raw Any payloads for requested item type IDs\n items-raw-all-pcb [--debug] Dump all PCB item payloads across all PCB object types\n pad-shape-polygon --pad-id <uuid> ... --layer-id <i32> [--debug]\n Dump pad polygons on a target layer\n padstack-presence --item-id <uuid> ... --layer-id <i32> ... [--debug]\n Check padstack shape presence matrix across layers\n title-block Show title block fields\n board-as-string Dump board as KiCad s-expression text\n selection-as-string Dump current selection as KiCad s-expression text\n stackup Show typed board stackup\n graphics-defaults Show typed graphics defaults\n appearance Show typed editor appearance settings\n netclass Show typed netclass map for current board nets\n proto-coverage-board-read Print board-read command coverage vs proto\n board-read-report [--out P] Write markdown board reconstruction report\n enabled-layers List enabled board layers\n active-layer Show active board layer\n set-active-layer --layer-id <i32>\n Set active board layer\n visible-layers Show currently visible board layers\n set-visible-layers --layer-id <i32> ...\n Set visible board layers\n board-origin [--type <t>] Show board origin (`grid` default, or `drill`)\n set-board-origin --type <t> --x-nm <i64> --y-nm <i64>\n Set board origin (`grid` or `drill`)\n refresh-editor [--frame <f>] Refresh a specific editor frame (default: pcb)\n begin-commit Start staged commit and print commit ID\n end-commit --id <uuid> [--action <commit|drop>] [--message <text>]\n End staged commit with commit/drop action\n selection-summary Show current selection item type counts\n selection-details Show parsed details for selected items\n selection-raw Show raw Any payload bytes for selected items\n smoke ping + version + board-open summary\n help Show help\n\nTYPES:\n schematic | symbol | pcb | footprint | drawing-sheet | project\n"
|
"kicad-ipc-cli\n\nUSAGE:\n cargo run --bin kicad-ipc-cli -- [--socket URI] [--token TOKEN] [--client-name NAME] [--timeout-ms N] <command> [command options]\n\nCOMMANDS:\n ping Check IPC connectivity\n version Fetch KiCad version\n open-docs [--type <type>] List open docs (default type: pcb)\n project-path Get current project path from open PCB docs\n board-open Exit non-zero if no PCB doc is open\n net-classes List project netclass definitions\n text-variables List text variables for current board document\n expand-text-variables Expand variables in provided text values\n Options: --text <value> (repeatable)\n text-extents Measure text bounding box\n Options: --text <value>\n text-as-shapes Convert text to rendered shapes\n Options: --text <value> (repeatable)\n nets List board nets (requires one open PCB)\n netlist-pads Emit pad-level netlist data (with footprint context)\n items-by-id --id <uuid> ... Show parsed details for specific item IDs\n item-bbox --id <uuid> ... Show bounding boxes for item IDs\n hit-test --id <uuid> --x-nm <x> --y-nm <y> [--tolerance-nm <n>]\n Hit-test one item at a point\n types-pcb List PCB KiCad object type IDs from proto enum\n items-raw --type-id <id> ... Dump raw Any payloads for requested item type IDs\n items-raw-all-pcb [--debug] Dump all PCB item payloads across all PCB object types\n pad-shape-polygon --pad-id <uuid> ... --layer-id <i32> [--debug]\n Dump pad polygons on a target layer\n padstack-presence --item-id <uuid> ... --layer-id <i32> ... [--debug]\n Check padstack shape presence matrix across layers\n title-block Show title block fields\n board-as-string Dump board as KiCad s-expression text\n selection-as-string Dump current selection as KiCad s-expression text\n stackup Show typed board stackup\n graphics-defaults Show typed graphics defaults\n appearance Show typed editor appearance settings\n netclass Show typed netclass map for current board nets\n proto-coverage-board-read Print board-read command coverage vs proto\n board-read-report [--out P] Write markdown board reconstruction report\n enabled-layers List enabled board layers\n set-enabled-layers --copper-layer-count <u32> [--layer-id <i32> ...]\n Set enabled board layer set\n active-layer Show active board layer\n set-active-layer --layer-id <i32>\n Set active board layer\n visible-layers Show currently visible board layers\n set-visible-layers --layer-id <i32> ...\n Set visible board layers\n board-origin [--type <t>] Show board origin (`grid` default, or `drill`)\n set-board-origin --type <t> --x-nm <i64> --y-nm <i64>\n Set board origin (`grid` or `drill`)\n refresh-editor [--frame <f>] Refresh a specific editor frame (default: pcb)\n begin-commit Start staged commit and print commit ID\n end-commit --id <uuid> [--action <commit|drop>] [--message <text>]\n End staged commit with commit/drop action\n selection-summary Show current selection item type counts\n selection-details Show parsed details for selected items\n selection-raw Show raw Any payload bytes for selected items\n smoke ping + version + board-open summary\n help Show help\n\nTYPES:\n schematic | symbol | pcb | footprint | drawing-sheet | project\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1926,6 +1985,31 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_args_parses_set_enabled_layers() {
|
||||||
|
let (_, command) = parse_args_from(vec![
|
||||||
|
"set-enabled-layers".to_string(),
|
||||||
|
"--copper-layer-count".to_string(),
|
||||||
|
"2".to_string(),
|
||||||
|
"--layer-id".to_string(),
|
||||||
|
"47".to_string(),
|
||||||
|
"--layer-id".to_string(),
|
||||||
|
"52".to_string(),
|
||||||
|
])
|
||||||
|
.expect("set-enabled-layers args should parse");
|
||||||
|
|
||||||
|
match command {
|
||||||
|
Command::SetEnabledLayers {
|
||||||
|
copper_layer_count,
|
||||||
|
layer_ids,
|
||||||
|
} => {
|
||||||
|
assert_eq!(copper_layer_count, 2);
|
||||||
|
assert_eq!(layer_ids, vec![47, 52]);
|
||||||
|
}
|
||||||
|
other => panic!("unexpected command variant: {other:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_args_parses_set_visible_layers() {
|
fn parse_args_parses_set_visible_layers() {
|
||||||
let (_, command) = parse_args_from(vec![
|
let (_, command) = parse_args_from(vec![
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue