feat(common): add UpdateItems API and CLI command

This commit is contained in:
Milind Sharma 2026-02-20 18:36:18 +08:00
parent 01ed710ae2
commit b26a04e392
4 changed files with 116 additions and 4 deletions

View File

@ -40,6 +40,7 @@ Deferred manual/runtime verification (implemented after 2026-02-20 while user un
- `RevertDocument` - `RevertDocument`
- `RunAction` - `RunAction`
- `CreateItems` - `CreateItems`
- `UpdateItems`
## KiCad v10 RC1.1 API Completion Matrix ## KiCad v10 RC1.1 API Completion Matrix
@ -60,11 +61,11 @@ Legend:
| Section | Proto Commands | Implemented | Coverage | | Section | Proto Commands | Implemented | Coverage |
| --- | ---: | ---: | ---: | | --- | ---: | ---: | ---: |
| Common (base) | 6 | 6 | 100% | | Common (base) | 6 | 6 | 100% |
| Common editor/document | 23 | 20 | 87% | | Common editor/document | 23 | 21 | 91% |
| Project manager | 5 | 3 | 60% | | Project manager | 5 | 3 | 60% |
| Board editor (PCB) | 22 | 20 | 91% | | Board editor (PCB) | 22 | 20 | 91% |
| Schematic editor (dedicated proto commands) | 0 | 0 | n/a | | Schematic editor (dedicated proto commands) | 0 | 0 | n/a |
| **Total** | **56** | **49** | **88%** | | **Total** | **56** | **50** | **89%** |
### Common (base) ### Common (base)
@ -92,7 +93,7 @@ Legend:
| `CreateItems` | Implemented | `KiCadClient::create_items_raw`, `KiCadClient::create_items` | | `CreateItems` | Implemented | `KiCadClient::create_items_raw`, `KiCadClient::create_items` |
| `GetItems` | Implemented | `KiCadClient::get_items_raw_by_type_codes`, `KiCadClient::get_items_by_type_codes`, `KiCadClient::get_items_details_by_type_codes`, `KiCadClient::get_all_pcb_items_raw`, `KiCadClient::get_all_pcb_items`, `KiCadClient::get_all_pcb_items_details`, `KiCadClient::get_pad_netlist` | | `GetItems` | Implemented | `KiCadClient::get_items_raw_by_type_codes`, `KiCadClient::get_items_by_type_codes`, `KiCadClient::get_items_details_by_type_codes`, `KiCadClient::get_all_pcb_items_raw`, `KiCadClient::get_all_pcb_items`, `KiCadClient::get_all_pcb_items_details`, `KiCadClient::get_pad_netlist` |
| `GetItemsById` | Implemented | `KiCadClient::get_items_by_id_raw`, `KiCadClient::get_items_by_id`, `KiCadClient::get_items_by_id_details` | | `GetItemsById` | Implemented | `KiCadClient::get_items_by_id_raw`, `KiCadClient::get_items_by_id`, `KiCadClient::get_items_by_id_details` |
| `UpdateItems` | Not yet | - | | `UpdateItems` | Implemented | `KiCadClient::update_items_raw`, `KiCadClient::update_items` |
| `DeleteItems` | Not yet | - | | `DeleteItems` | Not yet | - |
| `GetBoundingBox` | Implemented | `KiCadClient::get_item_bounding_boxes` | | `GetBoundingBox` | Implemented | `KiCadClient::get_item_bounding_boxes` |
| `GetSelection` | Implemented | `KiCadClient::get_selection_raw`, `KiCadClient::get_selection`, `KiCadClient::get_selection_summary`, `KiCadClient::get_selection_details` | | `GetSelection` | Implemented | `KiCadClient::get_selection_raw`, `KiCadClient::get_selection`, `KiCadClient::get_selection_summary`, `KiCadClient::get_selection_details` |

View File

@ -193,6 +193,12 @@ Create raw Any item payload(s):
cargo run --bin kicad-ipc-cli -- create-items --item type.googleapis.com/kiapi.board.types.Text=<hex_payload> cargo run --bin kicad-ipc-cli -- create-items --item type.googleapis.com/kiapi.board.types.Text=<hex_payload>
``` ```
Update raw Any item payload(s):
```bash
cargo run --bin kicad-ipc-cli -- update-items --item type.googleapis.com/kiapi.board.types.Text=<hex_payload>
```
Show summary of current PCB selection by item type: Show summary of current PCB selection by item type:
```bash ```bash

View File

@ -77,6 +77,7 @@ const CMD_CLEAR_SELECTION: &str = "kiapi.common.commands.ClearSelection";
const CMD_BEGIN_COMMIT: &str = "kiapi.common.commands.BeginCommit"; const CMD_BEGIN_COMMIT: &str = "kiapi.common.commands.BeginCommit";
const CMD_END_COMMIT: &str = "kiapi.common.commands.EndCommit"; const CMD_END_COMMIT: &str = "kiapi.common.commands.EndCommit";
const CMD_CREATE_ITEMS: &str = "kiapi.common.commands.CreateItems"; const CMD_CREATE_ITEMS: &str = "kiapi.common.commands.CreateItems";
const CMD_UPDATE_ITEMS: &str = "kiapi.common.commands.UpdateItems";
const CMD_GET_ITEMS: &str = "kiapi.common.commands.GetItems"; const CMD_GET_ITEMS: &str = "kiapi.common.commands.GetItems";
const CMD_GET_ITEMS_BY_ID: &str = "kiapi.common.commands.GetItemsById"; const CMD_GET_ITEMS_BY_ID: &str = "kiapi.common.commands.GetItemsById";
const CMD_GET_BOUNDING_BOX: &str = "kiapi.common.commands.GetBoundingBox"; const CMD_GET_BOUNDING_BOX: &str = "kiapi.common.commands.GetBoundingBox";
@ -116,6 +117,7 @@ const RES_SELECTION_RESPONSE: &str = "kiapi.common.commands.SelectionResponse";
const RES_BEGIN_COMMIT_RESPONSE: &str = "kiapi.common.commands.BeginCommitResponse"; const RES_BEGIN_COMMIT_RESPONSE: &str = "kiapi.common.commands.BeginCommitResponse";
const RES_END_COMMIT_RESPONSE: &str = "kiapi.common.commands.EndCommitResponse"; const RES_END_COMMIT_RESPONSE: &str = "kiapi.common.commands.EndCommitResponse";
const RES_CREATE_ITEMS_RESPONSE: &str = "kiapi.common.commands.CreateItemsResponse"; const RES_CREATE_ITEMS_RESPONSE: &str = "kiapi.common.commands.CreateItemsResponse";
const RES_UPDATE_ITEMS_RESPONSE: &str = "kiapi.common.commands.UpdateItemsResponse";
const RES_GET_ITEMS_RESPONSE: &str = "kiapi.common.commands.GetItemsResponse"; const RES_GET_ITEMS_RESPONSE: &str = "kiapi.common.commands.GetItemsResponse";
const RES_GET_BOUNDING_BOX_RESPONSE: &str = "kiapi.common.commands.GetBoundingBoxResponse"; const RES_GET_BOUNDING_BOX_RESPONSE: &str = "kiapi.common.commands.GetBoundingBoxResponse";
const RES_HIT_TEST_RESPONSE: &str = "kiapi.common.commands.HitTestResponse"; const RES_HIT_TEST_RESPONSE: &str = "kiapi.common.commands.HitTestResponse";
@ -657,6 +659,42 @@ impl KiCadClient {
.collect() .collect()
} }
pub async fn update_items_raw(
&self,
items: Vec<prost_types::Any>,
) -> Result<prost_types::Any, KiCadError> {
let command = common_commands::UpdateItems {
header: Some(self.current_board_item_header().await?),
items,
};
let response = self
.send_command(envelope::pack_any(&command, CMD_UPDATE_ITEMS))
.await?;
response_payload_as_any(response, RES_UPDATE_ITEMS_RESPONSE)
}
pub async fn update_items(
&self,
items: Vec<prost_types::Any>,
) -> Result<Vec<prost_types::Any>, KiCadError> {
let payload = self.update_items_raw(items).await?;
let response: common_commands::UpdateItemsResponse =
decode_any(&payload, RES_UPDATE_ITEMS_RESPONSE)?;
ensure_item_request_ok(response.status)?;
response
.updated_items
.into_iter()
.map(|row| {
ensure_item_status_ok(row.status)?;
row.item.ok_or_else(|| KiCadError::InvalidResponse {
reason: "UpdateItemsResponse missing updated item payload".to_string(),
})
})
.collect()
}
pub async fn get_nets(&self) -> Result<Vec<BoardNet>, KiCadError> { pub async fn get_nets(&self) -> Result<Vec<BoardNet>, KiCadError> {
let board = self.current_board_document_proto().await?; let board = self.current_board_document_proto().await?;
let command = board_commands::GetNets { let command = board_commands::GetNets {

File diff suppressed because one or more lines are too long