type QueryResult = Result<QueryResolution, String>
This commit is contained in:
@@ -1,17 +1,17 @@
|
|||||||
use super::{Machine, MachineConfig, QueryResult, QueryResultLine, Atom};
|
use super::{Machine, MachineConfig, QueryResult, QueryResolution, QueryResolutionLine, Atom};
|
||||||
|
|
||||||
impl Machine {
|
impl Machine {
|
||||||
pub fn new_lib() -> Self {
|
pub fn new_lib() -> Self {
|
||||||
Machine::new(MachineConfig::in_memory().with_toplevel(include_str!("../lib_toplevel.pl")))
|
Machine::new(MachineConfig::in_memory().with_toplevel(include_str!("../lib_toplevel.pl")))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_query(&mut self, query: String) -> Result<QueryResult, String> {
|
pub fn run_query(&mut self, query: String) -> QueryResult {
|
||||||
self.set_user_input(query);
|
self.set_user_input(query);
|
||||||
self.run_top_level(atom!("$toplevel"), (atom!("run_input_once"), 0));
|
self.run_top_level(atom!("$toplevel"), (atom!("run_input_once"), 0));
|
||||||
self.parse_output()
|
self.parse_output()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_output(&self) -> Result<QueryResult, String> {
|
pub fn parse_output(&self) -> QueryResult {
|
||||||
let output = self.get_user_output().trim().to_string();
|
let output = self.get_user_output().trim().to_string();
|
||||||
if output.starts_with("error(") {
|
if output.starts_with("error(") {
|
||||||
Err(output)
|
Err(output)
|
||||||
@@ -21,9 +21,9 @@ impl Machine {
|
|||||||
.map(|s| s.trim())
|
.map(|s| s.trim())
|
||||||
.map(|s| s.replace(".", ""))
|
.map(|s| s.replace(".", ""))
|
||||||
.filter(|s| !s.is_empty())
|
.filter(|s| !s.is_empty())
|
||||||
.map(QueryResultLine::try_from)
|
.map(QueryResolutionLine::try_from)
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
.collect::<Vec<QueryResultLine>>()
|
.collect::<Vec<QueryResolutionLine>>()
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ mod tests {
|
|||||||
let output = machine.run_query(query);
|
let output = machine.run_query(query);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
output,
|
output,
|
||||||
Ok(QueryResult::Matches(vec![
|
Ok(QueryResolution::Matches(vec![
|
||||||
QueryMatch::from(btreemap! {
|
QueryMatch::from(btreemap! {
|
||||||
"P" => Value::from("p1"),
|
"P" => Value::from("p1"),
|
||||||
}),
|
}),
|
||||||
@@ -64,12 +64,12 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
machine.run_query(String::from(r#"triple("a","p1","b")."#)),
|
machine.run_query(String::from(r#"triple("a","p1","b")."#)),
|
||||||
Ok(QueryResult::True)
|
Ok(QueryResolution::True)
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
machine.run_query(String::from(r#"triple("x","y","z")."#)),
|
machine.run_query(String::from(r#"triple("x","y","z")."#)),
|
||||||
Ok(QueryResult::False)
|
Ok(QueryResolution::False)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ use ordered_float::OrderedFloat;
|
|||||||
use rug::*;
|
use rug::*;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
pub type QueryResult = Result<QueryResolution, String>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum QueryResult {
|
pub enum QueryResolution {
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
Matches(Vec<QueryMatch>),
|
Matches(Vec<QueryMatch>),
|
||||||
@@ -16,7 +18,7 @@ pub struct QueryMatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum QueryResultLine {
|
pub enum QueryResolutionLine {
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
Match(BTreeMap<String, Value>),
|
Match(BTreeMap<String, Value>),
|
||||||
@@ -51,13 +53,13 @@ impl From<BTreeMap<String, Value>> for QueryMatch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<QueryResultLine>> for QueryResult {
|
impl From<Vec<QueryResolutionLine>> for QueryResolution {
|
||||||
fn from(query_result_lines: Vec<QueryResultLine>) -> Self {
|
fn from(query_result_lines: Vec<QueryResolutionLine>) -> Self {
|
||||||
// If there is only one line, and it is true or false, return that.
|
// If there is only one line, and it is true or false, return that.
|
||||||
if query_result_lines.len() == 1 {
|
if query_result_lines.len() == 1 {
|
||||||
match query_result_lines[0].clone() {
|
match query_result_lines[0].clone() {
|
||||||
QueryResultLine::True => return QueryResult::True,
|
QueryResolutionLine::True => return QueryResolution::True,
|
||||||
QueryResultLine::False => return QueryResult::False,
|
QueryResolutionLine::False => return QueryResolution::False,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,49 +67,49 @@ impl From<Vec<QueryResultLine>> for QueryResult {
|
|||||||
// If there is at least one line with true and no matches, return true.
|
// If there is at least one line with true and no matches, return true.
|
||||||
if query_result_lines
|
if query_result_lines
|
||||||
.iter()
|
.iter()
|
||||||
.any(|l| l == &QueryResultLine::True)
|
.any(|l| l == &QueryResolutionLine::True)
|
||||||
&& !query_result_lines.iter().any(|l| {
|
&& !query_result_lines.iter().any(|l| {
|
||||||
if let &QueryResultLine::Match(_) = l {
|
if let &QueryResolutionLine::Match(_) = l {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
return QueryResult::True;
|
return QueryResolution::True;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is at least one match, return all matches.
|
// If there is at least one match, return all matches.
|
||||||
let all_matches = query_result_lines
|
let all_matches = query_result_lines
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|l| {
|
.filter(|l| {
|
||||||
if let &QueryResultLine::Match(_) = l {
|
if let &QueryResolutionLine::Match(_) = l {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|l| match l {
|
.map(|l| match l {
|
||||||
QueryResultLine::Match(m) => QueryMatch::from(m),
|
QueryResolutionLine::Match(m) => QueryMatch::from(m),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if !all_matches.is_empty() {
|
if !all_matches.is_empty() {
|
||||||
return QueryResult::Matches(all_matches);
|
return QueryResolution::Matches(all_matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryResult::False
|
QueryResolution::False
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<String> for QueryResultLine {
|
impl TryFrom<String> for QueryResolutionLine {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
fn try_from(string: String) -> Result<Self, Self::Error> {
|
fn try_from(string: String) -> Result<Self, Self::Error> {
|
||||||
match string.as_str() {
|
match string.as_str() {
|
||||||
"true" => Ok(QueryResultLine::True),
|
"true" => Ok(QueryResolutionLine::True),
|
||||||
"false" => Ok(QueryResultLine::False),
|
"false" => Ok(QueryResolutionLine::False),
|
||||||
_ => Ok(QueryResultLine::Match(
|
_ => Ok(QueryResolutionLine::Match(
|
||||||
string
|
string
|
||||||
.split(",")
|
.split(",")
|
||||||
.map(|s| s.trim())
|
.map(|s| s.trim())
|
||||||
|
|||||||
Reference in New Issue
Block a user