mod form;
pub(crate) mod guide;
pub(crate) mod lookup;
mod question;
mod records;
pub(crate) mod setup;
#[cfg(test)]
mod tests;
use std::collections::HashMap;
use argonauts_core::asking::AskReply;
use argonauts_core::events::approval::AnswerAction;
use argonauts_core::names::{ChoiceId, TurnId};
use argonauts_core::required::{RequiredStep, same_name};
use super::ConversationState;
use crate::controller::{Ctx, Effect};
use super::tools::Call;
fn fail(call: Call, text: impl Into<String>) {
let _ = call.reply.send(AskReply {
text: text.into(),
is_error: true,
});
}
#[derive(Default)]
pub(crate) struct TalkState {
questions: HashMap<ChoiceId, question::Open>,
for_request: Option<(TurnId, Vec<(String, String)>)>,
steps_for_request: Option<(TurnId, Vec<RequiredStep>)>,
steps_for_conversation: Vec<RequiredStep>,
}
pub(crate) fn owns(conversation: &ConversationState, id: &ChoiceId) -> bool {
conversation.talk.questions.contains_key(id)
}
pub(crate) fn answer(
ctx: &mut Ctx,
conversation: &mut ConversationState,
id: ChoiceId,
action: AnswerAction,
) -> anyhow::Result<Vec<Effect>> {
question::answer(ctx, conversation, id, action)
}
pub(crate) fn set_aside(
ctx: &mut Ctx,
conversation: &mut ConversationState,
id: ChoiceId,
) -> Vec<Effect> {
question::not_now(ctx, conversation, id)
}
pub(crate) fn settle_on_autopilot(
ctx: &mut Ctx,
conversation: &mut ConversationState,
) -> Vec<Effect> {
question::settle_on_autopilot(ctx, conversation)
}
pub(crate) fn request_settings(conversation: &mut ConversationState, turn: &TurnId) -> Vec<String> {
match conversation.talk.for_request.take() {
Some((kept_for, pairs)) if &kept_for == turn => pairs
.into_iter()
.map(|(key, value)| format!("{key}={value}"))
.collect(),
_ => Vec::new(),
}
}
pub(crate) fn conversation_steps(conversation: &ConversationState) -> &[RequiredStep] {
&conversation.talk.steps_for_conversation
}
pub(crate) fn required_steps(
conversation: &mut ConversationState,
turn: &TurnId,
) -> Vec<RequiredStep> {
let mut steps = conversation.talk.steps_for_conversation.clone();
if let Some((kept_for, kept)) = conversation.talk.steps_for_request.take()
&& &kept_for == turn
{
for step in kept {
steps.retain(|known| !same_name(&known.name, &step.name));
steps.push(step);
}
}
steps
}