mod metrics;
mod migration;
mod render;
mod schema;
mod snapshot;
use crate::cli::{
CanisterTarget, DiagnosticArtifactArgs, DiagnosticSourceMetadataArgs, MetricsArgs,
SchemaMigrationCommand,
};
use crate::icp::{call_query_hex, call_update_hex, encode_wire_args};
use serde::de::DeserializeOwned;
pub(crate) fn run_metrics_command(args: MetricsArgs) -> Result<(), String> {
metrics::run_metrics_command(args)
}
pub(crate) fn run_schema_show_command(target: CanisterTarget) -> Result<(), String> {
schema::run_schema_show_command(target)
}
pub(crate) fn run_diagnostic_artifact_command(args: DiagnosticArtifactArgs) -> Result<(), String> {
schema::run_diagnostic_artifact_command(args)
}
pub(crate) fn run_diagnostic_source_metadata_command(
args: DiagnosticSourceMetadataArgs,
) -> Result<(), String> {
schema::run_diagnostic_source_metadata_command(args)
}
pub(crate) fn load_schema_report(
environment: &str,
canister: &str,
) -> Result<Vec<icydb::db::EntitySchemaDescription>, String> {
schema::load_schema_report(environment, canister)
}
pub(crate) fn run_schema_migration_command(command: SchemaMigrationCommand) -> Result<(), String> {
migration::run_schema_migration_command(command)
}
pub(crate) fn run_snapshot_command(target: CanisterTarget) -> Result<(), String> {
snapshot::run_snapshot_command(target)
}
fn call_query(
environment: &str,
canister: &str,
method: &str,
arguments: impl serde::Serialize,
) -> Result<Vec<u8>, String> {
call_query_hex(
environment,
canister,
method,
&encode_wire_args(method, arguments)?,
call_error_mapper("query", environment, canister, method),
)
}
fn call_update(
environment: &str,
canister: &str,
method: &str,
arguments: impl serde::Serialize,
) -> Result<Vec<u8>, String> {
call_update_hex(
environment,
canister,
method,
&encode_wire_args(method, arguments)?,
call_error_mapper("update", environment, canister, method),
)
}
fn call_error_mapper<'a>(
label: &'a str,
environment: &'a str,
canister: &'a str,
method: &'a str,
) -> impl FnOnce(&str) -> String + 'a {
move |stderr| method_error(label, environment, canister, method, stderr)
}
pub(crate) fn decode_endpoint_result<T: serde::Serialize + DeserializeOwned>(
bytes: &[u8],
label: &str,
environment: &str,
canister: &str,
method: &str,
) -> Result<T, String> {
let response = icydb::wire::Endpoint::from_name(method)
.ok_or_else(|| format!("unknown IcyDB method '{method}'"))?
.decode_response::<Result<T, icydb::Error>>(bytes)
.map_err(|error| error.to_string())?;
response.map_err(|error| {
method_error(
label,
environment,
canister,
method,
&crate::diagnostic::render_error(&error),
)
})
}
fn method_error(
label: &str,
environment: &str,
canister: &str,
method: &str,
detail: &str,
) -> String {
format!(
"IcyDB {label} method '{method}' failed on canister '{canister}' in environment '{environment}': {detail}",
)
}
#[cfg(test)]
pub(crate) mod test_support {
use crate::observability::{
method_error as base_method_error, metrics, render, schema, snapshot,
};
pub(crate) fn method_error(
label: &str,
environment: &str,
canister: &str,
method: &str,
detail: &str,
) -> String {
base_method_error(label, environment, canister, method, detail)
}
pub(crate) fn render_field_list(fields: &[String]) -> String {
render::render_field_list(fields)
}
pub(crate) fn render_metrics_report(report: &icydb::metrics::MetricsReport) -> String {
metrics::render_metrics_report(report)
}
pub(crate) fn render_schema_report(report: &[icydb::db::EntitySchemaDescription]) -> String {
schema::render_schema_report(report)
}
pub(crate) fn render_snapshot_report(report: &icydb::db::StorageReport) -> String {
snapshot::render_snapshot_report(report)
}
pub(crate) const fn yes_no(value: bool) -> &'static str {
render::yes_no(value)
}
}