feat(common): add RunAction API and CLI command
This commit is contained in:
parent
e03bc9ab89
commit
a29a573c6d
|
|
@ -38,6 +38,7 @@ Deferred manual/runtime verification (implemented after 2026-02-20 while user un
|
||||||
- `SaveDocument`
|
- `SaveDocument`
|
||||||
- `SaveCopyOfDocument`
|
- `SaveCopyOfDocument`
|
||||||
- `RevertDocument`
|
- `RevertDocument`
|
||||||
|
- `RunAction`
|
||||||
|
|
||||||
## KiCad v10 RC1.1 API Completion Matrix
|
## KiCad v10 RC1.1 API Completion Matrix
|
||||||
|
|
||||||
|
|
@ -58,11 +59,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 | 18 | 78% |
|
| Common editor/document | 23 | 19 | 83% |
|
||||||
| 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** | **47** | **84%** |
|
| **Total** | **56** | **48** | **86%** |
|
||||||
|
|
||||||
### Common (base)
|
### Common (base)
|
||||||
|
|
||||||
|
|
@ -84,7 +85,7 @@ Legend:
|
||||||
| `SaveDocument` | Implemented | `KiCadClient::save_document_raw`, `KiCadClient::save_document` |
|
| `SaveDocument` | Implemented | `KiCadClient::save_document_raw`, `KiCadClient::save_document` |
|
||||||
| `SaveCopyOfDocument` | Implemented | `KiCadClient::save_copy_of_document_raw`, `KiCadClient::save_copy_of_document` |
|
| `SaveCopyOfDocument` | Implemented | `KiCadClient::save_copy_of_document_raw`, `KiCadClient::save_copy_of_document` |
|
||||||
| `RevertDocument` | Implemented | `KiCadClient::revert_document_raw`, `KiCadClient::revert_document` |
|
| `RevertDocument` | Implemented | `KiCadClient::revert_document_raw`, `KiCadClient::revert_document` |
|
||||||
| `RunAction` | Not yet | - |
|
| `RunAction` | Implemented | `KiCadClient::run_action_raw`, `KiCadClient::run_action` |
|
||||||
| `BeginCommit` | Implemented | `KiCadClient::begin_commit_raw`, `KiCadClient::begin_commit` |
|
| `BeginCommit` | Implemented | `KiCadClient::begin_commit_raw`, `KiCadClient::begin_commit` |
|
||||||
| `EndCommit` | Implemented | `KiCadClient::end_commit_raw`, `KiCadClient::end_commit` |
|
| `EndCommit` | Implemented | `KiCadClient::end_commit_raw`, `KiCadClient::end_commit` |
|
||||||
| `CreateItems` | Not yet | - |
|
| `CreateItems` | Not yet | - |
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,12 @@ Revert current board document from disk:
|
||||||
cargo run --bin kicad-ipc-cli -- revert-doc
|
cargo run --bin kicad-ipc-cli -- revert-doc
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Run a raw KiCad tool action:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run --bin kicad-ipc-cli -- run-action --action pcbnew.InteractiveSelection.ClearSelection
|
||||||
|
```
|
||||||
|
|
||||||
Show summary of current PCB selection by item type:
|
Show summary of current PCB selection by item type:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ use crate::model::board::{
|
||||||
};
|
};
|
||||||
use crate::model::common::{
|
use crate::model::common::{
|
||||||
CommitAction, CommitSession, DocumentSpecifier, DocumentType, EditorFrameType, ItemBoundingBox,
|
CommitAction, CommitSession, DocumentSpecifier, DocumentType, EditorFrameType, ItemBoundingBox,
|
||||||
ItemHitTestResult, PcbObjectTypeCode, ProjectInfo, SelectionItemDetail, SelectionSummary,
|
ItemHitTestResult, PcbObjectTypeCode, ProjectInfo, RunActionStatus, SelectionItemDetail,
|
||||||
SelectionTypeCount, TextAsShapesEntry, TextAttributesSpec, TextBoxSpec, TextExtents,
|
SelectionSummary, SelectionTypeCount, TextAsShapesEntry, TextAttributesSpec, TextBoxSpec,
|
||||||
TextHorizontalAlignment, TextObjectSpec, TextShape, TextShapeGeometry, TextSpec,
|
TextExtents, TextHorizontalAlignment, TextObjectSpec, TextShape, TextShapeGeometry, TextSpec,
|
||||||
TextVerticalAlignment, TitleBlockInfo, VersionInfo,
|
TextVerticalAlignment, TitleBlockInfo, VersionInfo,
|
||||||
};
|
};
|
||||||
use crate::proto::kiapi::board as board_proto;
|
use crate::proto::kiapi::board as board_proto;
|
||||||
|
|
@ -46,6 +46,7 @@ const CMD_GET_TEXT_EXTENTS: &str = "kiapi.common.commands.GetTextExtents";
|
||||||
const CMD_GET_TEXT_AS_SHAPES: &str = "kiapi.common.commands.GetTextAsShapes";
|
const CMD_GET_TEXT_AS_SHAPES: &str = "kiapi.common.commands.GetTextAsShapes";
|
||||||
const CMD_REFRESH_EDITOR: &str = "kiapi.common.commands.RefreshEditor";
|
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_RUN_ACTION: &str = "kiapi.common.commands.RunAction";
|
||||||
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_SET_BOARD_ENABLED_LAYERS: &str = "kiapi.board.commands.SetBoardEnabledLayers";
|
||||||
|
|
@ -96,6 +97,7 @@ const RES_EXPAND_TEXT_VARIABLES_RESPONSE: &str =
|
||||||
const RES_BOX2: &str = "kiapi.common.types.Box2";
|
const RES_BOX2: &str = "kiapi.common.types.Box2";
|
||||||
const RES_GET_TEXT_AS_SHAPES_RESPONSE: &str = "kiapi.common.commands.GetTextAsShapesResponse";
|
const RES_GET_TEXT_AS_SHAPES_RESPONSE: &str = "kiapi.common.commands.GetTextAsShapesResponse";
|
||||||
const RES_GET_OPEN_DOCUMENTS: &str = "kiapi.common.commands.GetOpenDocumentsResponse";
|
const RES_GET_OPEN_DOCUMENTS: &str = "kiapi.common.commands.GetOpenDocumentsResponse";
|
||||||
|
const RES_RUN_ACTION_RESPONSE: &str = "kiapi.common.commands.RunActionResponse";
|
||||||
const RES_GET_NETS: &str = "kiapi.board.commands.NetsResponse";
|
const RES_GET_NETS: &str = "kiapi.board.commands.NetsResponse";
|
||||||
const RES_GET_BOARD_ENABLED_LAYERS: &str = "kiapi.board.commands.BoardEnabledLayersResponse";
|
const RES_GET_BOARD_ENABLED_LAYERS: &str = "kiapi.board.commands.BoardEnabledLayersResponse";
|
||||||
const RES_BOARD_LAYER_RESPONSE: &str = "kiapi.board.commands.BoardLayerResponse";
|
const RES_BOARD_LAYER_RESPONSE: &str = "kiapi.board.commands.BoardLayerResponse";
|
||||||
|
|
@ -325,6 +327,29 @@ impl KiCadClient {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn run_action_raw(
|
||||||
|
&self,
|
||||||
|
action: impl Into<String>,
|
||||||
|
) -> Result<prost_types::Any, KiCadError> {
|
||||||
|
let command = common_commands::RunAction {
|
||||||
|
action: action.into(),
|
||||||
|
};
|
||||||
|
let response = self
|
||||||
|
.send_command(envelope::pack_any(&command, CMD_RUN_ACTION))
|
||||||
|
.await?;
|
||||||
|
response_payload_as_any(response, RES_RUN_ACTION_RESPONSE)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn run_action(
|
||||||
|
&self,
|
||||||
|
action: impl Into<String>,
|
||||||
|
) -> Result<RunActionStatus, KiCadError> {
|
||||||
|
let payload = self.run_action_raw(action).await?;
|
||||||
|
let response: common_commands::RunActionResponse =
|
||||||
|
decode_any(&payload, RES_RUN_ACTION_RESPONSE)?;
|
||||||
|
Ok(map_run_action_status(response.status))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_version(&self) -> Result<VersionInfo, KiCadError> {
|
pub async fn get_version(&self) -> Result<VersionInfo, KiCadError> {
|
||||||
let command = envelope::pack_any(&common_commands::GetVersion {}, CMD_GET_VERSION);
|
let command = envelope::pack_any(&common_commands::GetVersion {}, CMD_GET_VERSION);
|
||||||
let response = self.send_command(command).await?;
|
let response = self.send_command(command).await?;
|
||||||
|
|
@ -2074,6 +2099,18 @@ fn map_hit_test_result(value: i32) -> ItemHitTestResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn map_run_action_status(value: i32) -> RunActionStatus {
|
||||||
|
let status = common_commands::RunActionStatus::try_from(value)
|
||||||
|
.unwrap_or(common_commands::RunActionStatus::RasUnknown);
|
||||||
|
|
||||||
|
match status {
|
||||||
|
common_commands::RunActionStatus::RasOk => RunActionStatus::Ok,
|
||||||
|
common_commands::RunActionStatus::RasInvalid => RunActionStatus::Invalid,
|
||||||
|
common_commands::RunActionStatus::RasFrameNotOpen => RunActionStatus::FrameNotOpen,
|
||||||
|
common_commands::RunActionStatus::RasUnknown => RunActionStatus::Unknown(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn map_polygon_with_holes(
|
fn map_polygon_with_holes(
|
||||||
polygon: common_types::PolygonWithHoles,
|
polygon: common_types::PolygonWithHoles,
|
||||||
) -> Result<PolygonWithHolesNm, KiCadError> {
|
) -> Result<PolygonWithHolesNm, KiCadError> {
|
||||||
|
|
@ -3149,10 +3186,11 @@ mod tests {
|
||||||
any_to_pretty_debug, board_editor_appearance_settings_to_proto, commit_action_to_proto,
|
any_to_pretty_debug, board_editor_appearance_settings_to_proto, commit_action_to_proto,
|
||||||
drc_severity_to_proto, ensure_item_request_ok, layer_to_model, map_commit_session,
|
drc_severity_to_proto, ensure_item_request_ok, layer_to_model, map_commit_session,
|
||||||
map_hit_test_result, map_item_bounding_boxes, map_polygon_with_holes,
|
map_hit_test_result, map_item_bounding_boxes, map_polygon_with_holes,
|
||||||
model_document_to_proto, normalize_socket_uri, pad_netlist_from_footprint_items,
|
map_run_action_status, model_document_to_proto, normalize_socket_uri,
|
||||||
response_payload_as_any, select_single_board_document, select_single_project_path,
|
pad_netlist_from_footprint_items, response_payload_as_any, select_single_board_document,
|
||||||
selection_item_detail, summarize_item_details, summarize_selection,
|
select_single_project_path, selection_item_detail, summarize_item_details,
|
||||||
text_horizontal_alignment_to_proto, text_spec_to_proto, PCB_OBJECT_TYPES,
|
summarize_selection, text_horizontal_alignment_to_proto, text_spec_to_proto,
|
||||||
|
PCB_OBJECT_TYPES,
|
||||||
};
|
};
|
||||||
use crate::error::KiCadError;
|
use crate::error::KiCadError;
|
||||||
use crate::model::common::{
|
use crate::model::common::{
|
||||||
|
|
@ -3607,6 +3645,32 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn map_run_action_status_covers_known_variants() {
|
||||||
|
assert_eq!(
|
||||||
|
map_run_action_status(
|
||||||
|
crate::proto::kiapi::common::commands::RunActionStatus::RasOk as i32
|
||||||
|
),
|
||||||
|
crate::model::common::RunActionStatus::Ok
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
map_run_action_status(
|
||||||
|
crate::proto::kiapi::common::commands::RunActionStatus::RasInvalid as i32
|
||||||
|
),
|
||||||
|
crate::model::common::RunActionStatus::Invalid
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
map_run_action_status(
|
||||||
|
crate::proto::kiapi::common::commands::RunActionStatus::RasFrameNotOpen as i32
|
||||||
|
),
|
||||||
|
crate::model::common::RunActionStatus::FrameNotOpen
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
map_run_action_status(1234),
|
||||||
|
crate::model::common::RunActionStatus::Unknown(1234)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn text_horizontal_alignment_to_proto_covers_known_variants() {
|
fn text_horizontal_alignment_to_proto_covers_known_variants() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ pub use crate::model::board::{
|
||||||
};
|
};
|
||||||
pub use crate::model::common::{
|
pub use crate::model::common::{
|
||||||
CommitAction, CommitSession, DocumentSpecifier, DocumentType, EditorFrameType, ItemBoundingBox,
|
CommitAction, CommitSession, DocumentSpecifier, DocumentType, EditorFrameType, ItemBoundingBox,
|
||||||
ItemHitTestResult, PcbObjectTypeCode, SelectionItemDetail, SelectionSummary,
|
ItemHitTestResult, PcbObjectTypeCode, RunActionStatus, SelectionItemDetail, SelectionSummary,
|
||||||
SelectionTypeCount, TextAsShapesEntry, TextAttributesSpec, TextBoxSpec, TextExtents,
|
SelectionTypeCount, TextAsShapesEntry, TextAttributesSpec, TextBoxSpec, TextExtents,
|
||||||
TextHorizontalAlignment, TextObjectSpec, TextShape, TextShapeGeometry, TextSpec,
|
TextHorizontalAlignment, TextObjectSpec, TextShape, TextShapeGeometry, TextSpec,
|
||||||
TextVerticalAlignment, TitleBlockInfo, VersionInfo,
|
TextVerticalAlignment, TitleBlockInfo, VersionInfo,
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,14 @@ pub enum CommitAction {
|
||||||
Drop,
|
Drop,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
pub enum RunActionStatus {
|
||||||
|
Ok,
|
||||||
|
Invalid,
|
||||||
|
FrameNotOpen,
|
||||||
|
Unknown(i32),
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for CommitAction {
|
impl std::fmt::Display for CommitAction {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue