use super::Pump;
use serde_json::{Value, json};
impl Pump {
pub(super) fn configure(&mut self, change: &Value) -> anyhow::Result<()> {
let (Some(option), Some(value)) = (change["option"].as_str(), change.get("value")) else {
return self.publish_config();
};
anyhow::ensure!(
value.is_string() || value.is_boolean(),
"config value is neither text nor a switch"
);
if self.configuring.is_some() {
return self
.stream(json!({"type":"config_failed","reason":"a change is already in flight"}));
}
let id = self.next_id;
self.next_id = id
.checked_add(1)
.ok_or_else(|| anyhow::anyhow!("ACP request id exhausted"))?;
self.configuring = Some(id);
self.output.request(
id,
"session/set_config_option",
json!({"sessionId":self.session.id,"configId":option,"value":value}),
)
}
pub(super) fn configured(&mut self, result: Result<Value, i64>) -> anyhow::Result<()> {
self.configuring = None;
match result {
Ok(answer) => {
if let Some(options) = answer
.get("configOptions")
.filter(|options| options.is_array())
{
self.session.config = options.clone();
}
self.publish_config()
}
Err(code) => self.stream(json!({"type":"config_failed","code":code})),
}
}
fn publish_config(&self) -> anyhow::Result<()> {
self.stream(json!({"type":"config_options","options":self.session.config}))
}
pub fn draft_failed(&mut self, key: &str, error: &anyhow::Error) -> anyhow::Result<()> {
let Some(pending) = self.pending.remove(key) else {
return Ok(());
};
let decided = if pending.cancelled {
"cancelled"
} else {
self.output.response(
pending.id,
super::decide(&pending.request, super::Decision::Refused),
)?;
"deny"
};
self.stream(json!({"type":"permission_ask","decided":decided,"request":{"refused":error.to_string()}}))
}
fn stream(&self, item: Value) -> anyhow::Result<()> {
self.publications
.try_send(super::Publish::Stream(item))
.map_err(|_| anyhow::anyhow!("stream_queue reached or publisher closed"))
}
}