//! The native core methods and their JSON parameters. use crate::{Host, RpcResult, error}; use serde_json::{Value, json}; impl Host { /// Execute a core method without starting a guest process. pub(crate) async fn core( &self, caller: &str, id: Option, method: &str, p: Value, ) -> RpcResult { match method { "watch" => self.watch(caller, id, required_str(&p, "path")?).await, "call" => { self.route( caller.into(), id, required_str(&p, "method")?.into(), p.get("params").cloned().unwrap_or(json!({})), p["detach"].as_bool().unwrap_or(false), ) .await } "notify" => { self.notify( caller, required_str(&p, "name")?, p.get("params").cloned().unwrap_or(json!({})), ); Ok(Value::Null) } "kill" => { let pid = required_str(&p, "pid")?; let ended = self .0 .state .lock() .unwrap() .processes .get(pid) .map(|p| p.ended.subscribe()); self.kill(pid); if let Some(mut ended) = ended { let _ = ended.wait_for(|ended| *ended).await; } Ok(json!({})) } "stop" => { if let Some(mut n) = self.begin_stop(required_str(&p, "pid")?) { let _ = n.wait_for(|ended| *ended).await; } Ok(json!({})) } "lock" => { self.lock(caller, required_str(&p, "path")?, p["wait"] != false) .await } "unlock" => { self.unlock(caller, required_str(&p, "path")?); Ok(Value::Null) } "log" => Ok(self.0.journal.query(p).await), "activate" | "revert" => self.activation(caller, method, p).await, "restart" | "exit" => self.request_restart(), _ => Err(error(-32601, "method not found")), } } } fn required_str<'a>(params: &'a Value, name: &str) -> Result<&'a str, Value> { params[name] .as_str() .ok_or_else(|| error(-32602, &format!("{name} must be a string"))) }