Skip to main content

ic_host_tools/icp/
mod.rs

1//! ICP CLI command syntax and installation facts, without process execution.
2//!
3//! Callers select executables, credentials, environments, output formats and
4//! capture limits. No command is dispatched and no tool version is admitted here.
5
6mod status;
7#[cfg(test)]
8mod tests;
9
10use std::{ffi::OsStr, path::Path, process::Command};
11
12pub use status::{InstallationStatusError, decode_installation_status};
13
14/// The already-selected query or update operation; this does not authorize it.
15#[derive(Clone, Copy, Debug, Eq, PartialEq)]
16pub enum CallMode {
17    /// Append ICP CLI's query switch.
18    Query,
19    /// Use ICP CLI's default update operation.
20    Update,
21}
22
23/// The caller-owned Candid argument representation.
24#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub enum CallArguments<'a> {
26    /// Pass a textual Candid argument verbatim as one native argument.
27    Text(&'a OsStr),
28    /// Pass a file containing binary Candid; the caller owns its custody.
29    BinaryFile(&'a Path),
30}
31
32/// The caller-selected status output contract.
33#[derive(Clone, Copy, Debug, Eq, PartialEq)]
34pub enum StatusOutput {
35    /// Leave ICP CLI's output selection unchanged.
36    Text,
37    /// Request structured JSON.
38    Json,
39    /// Request only the canister id.
40    IdOnly,
41}
42
43/// Extend a caller-configured executable with an ICP canister call.
44///
45/// The base must not already contain the `canister` subcommand. Executable,
46/// native arguments, environment, working directory and standard I/O are retained.
47/// Callers append Candid interface, response format and target selection themselves.
48#[must_use]
49pub fn call_command(
50    mut command: Command,
51    canister: &OsStr,
52    method: &OsStr,
53    arguments: CallArguments<'_>,
54    mode: CallMode,
55) -> Command {
56    command.args([OsStr::new("canister"), OsStr::new("call"), canister, method]);
57    match arguments {
58        CallArguments::Text(argument) => {
59            command.arg(argument);
60        }
61        CallArguments::BinaryFile(path) => {
62            command
63                .arg("--args-file")
64                .arg(path)
65                .args(["--args-format", "bin"]);
66        }
67    }
68    if mode == CallMode::Query {
69        command.arg("--query");
70    }
71    command
72}
73
74/// Extend a caller-configured executable with an ICP canister status request.
75///
76/// The base must not already contain the `canister` subcommand. Target selection,
77/// capture, execution, failure interpretation and installation policy stay local.
78#[must_use]
79pub fn status_command(mut command: Command, canister: &OsStr, output: StatusOutput) -> Command {
80    command.args([OsStr::new("canister"), OsStr::new("status"), canister]);
81    match output {
82        StatusOutput::Text => {}
83        StatusOutput::Json => {
84            command.arg("--json");
85        }
86        StatusOutput::IdOnly => {
87            command.arg("--id-only");
88        }
89    }
90    command
91}