Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 35 additions & 31 deletions rust/agama-dbus-server/src/questions/answers.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashMap;

use agama_lib::questions::GenericQuestion;
use anyhow::Context;
use serde::{Deserialize, Serialize};

Expand All @@ -19,6 +20,37 @@ struct Answer {
pub password: Option<String>,
}

impl Answer {
/// Determines whether the answer responds to the given question.
///
/// * `question`: question to compare with.
pub fn responds(&self, question: &GenericQuestion) -> bool {
if let Some(class) = &self.class {
if question.class != *class {
return false;
}
}

if let Some(text) = &self.text {
if question.text != *text {
return false;
}
}

if let Some(data) = &self.data {
return data.iter().all(|(key, value)| {
let Some(e_val) = question.data.get(key) else {
return false;
};

e_val == value
});
}

true
}
}

/// Data structure holding list of Answer.
/// The first matching Answer is used, even if there is
/// a better (more specific) match later in the list.
Expand All @@ -40,36 +72,8 @@ impl Answers {
2
}

fn find_answer(&self, question: &agama_lib::questions::GenericQuestion) -> Option<&Answer> {
'main: for answerd in self.answers.iter() {
if let Some(v) = &answerd.class {
if !question.class.eq(v) {
continue;
}
}
if let Some(v) = &answerd.text {
if !question.text.eq(v) {
continue;
}
}
if let Some(v) = &answerd.data {
for (key, value) in v {
// all keys defined in answer has to match
let entry = question.data.get(key);
if let Some(e_val) = entry {
if !e_val.eq(value) {
continue 'main;
}
} else {
continue 'main;
}
}
}

return Some(answerd);
}

None
fn find_answer(&self, question: &GenericQuestion) -> Option<&Answer> {
self.answers.iter().find(|a| a.responds(&question))
}
}

Expand All @@ -78,7 +82,7 @@ impl crate::questions::AnswerStrategy for Answers {
Answers::id()
}

fn answer(&self, question: &agama_lib::questions::GenericQuestion) -> Option<String> {
fn answer(&self, question: &GenericQuestion) -> Option<String> {
let answer = self.find_answer(question);
answer.map(|answer| answer.answer.clone())
}
Expand Down