From e227b997383094d9fa2b01edf9dea0bc421fed4e Mon Sep 17 00:00:00 2001 From: bakaq Date: Mon, 19 Aug 2024 18:07:14 -0300 Subject: [PATCH] serde derive for QueryMatch --- Cargo.toml | 2 +- src/machine/lib_machine.rs | 3 ++- src/machine/parsed_results.rs | 41 +++++++++++------------------------ tests/scryer_lib/main.rs | 1 - 4 files changed, 16 insertions(+), 31 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eeb0eaa00..5800da979 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,7 +80,7 @@ ego-tree = "0.6.2" serde_json = "1.0.122" -serde = "1.0.204" +serde = { version="1.0.204", features = ["derive"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] crossterm = { version = "0.28.1", optional = true } diff --git a/src/machine/lib_machine.rs b/src/machine/lib_machine.rs index d8431ea0c..ab41ff01d 100644 --- a/src/machine/lib_machine.rs +++ b/src/machine/lib_machine.rs @@ -9,6 +9,7 @@ use crate::parser::parser::{Parser, Tokens}; use crate::read::{write_term_to_heap, TermWriteResult}; use indexmap::IndexMap; +use super::QueryMatch; use super::{ streams::Stream, Atom, AtomCell, HeapCellValue, HeapCellValueTag, Machine, MachineConfig, QueryResolutionLine, QueryResult, Value, @@ -138,7 +139,7 @@ impl Iterator for QueryState<'_> { // choice point, so we should break. self.machine.machine_st.backtrack(); - Some(Ok(QueryResolutionLine::Match(bindings))) + Some(Ok(QueryResolutionLine::Match(QueryMatch { bindings }))) } } diff --git a/src/machine/parsed_results.rs b/src/machine/parsed_results.rs index 6f0bfee0a..81bad1f35 100644 --- a/src/machine/parsed_results.rs +++ b/src/machine/parsed_results.rs @@ -22,27 +22,16 @@ use serde::Serializer; pub type QueryResult = Result; -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub struct QueryMatch { pub bindings: BTreeMap, } -impl Serialize for QueryMatch { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut map = serializer.serialize_map(Some(1))?; - map.serialize_entry("bindings", &self.bindings)?; - map.end() - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub enum QueryResolutionLine { True, False, - Match(BTreeMap), + Match(QueryMatch), } impl Serialize for QueryResolutionLine { @@ -53,11 +42,7 @@ impl Serialize for QueryResolutionLine { match self { QueryResolutionLine::True => serializer.serialize_bool(true), QueryResolutionLine::False => serializer.serialize_bool(false), - QueryResolutionLine::Match(m) => { - let mut map = serializer.serialize_map(Some(1))?; - map.serialize_entry("bindings", m)?; - map.end() - } + QueryResolutionLine::Match(m) => m.serialize(serializer), } } } @@ -142,7 +127,8 @@ impl From<&QueryResolutionLine> for Value { QueryResolutionLine::True => Value::Atom("true".into()), QueryResolutionLine::False => Value::Atom("false".into()), QueryResolutionLine::Match(m) => Value::conjunction( - &m.iter() + &m.bindings + .iter() .map(|(k, v)| { Value::Structure("=".into(), vec![Value::Var(k.clone()), v.clone()]) }) @@ -580,7 +566,7 @@ impl From> for QueryResolution { // If there is only one line, and it is an empty match, return false. if query_result_lines.len() == 1 { if let QueryResolutionLine::Match(m) = query_result_lines[0].clone() { - if m.is_empty() { + if m.bindings.is_empty() { return QueryResolution::False; } } @@ -600,10 +586,9 @@ impl From> for QueryResolution { // If there is at least one match, return all matches. let all_matches = query_result_lines .into_iter() - .filter(|l| matches!(l, QueryResolutionLine::Match(_))) - .map(|l| match l { - QueryResolutionLine::Match(m) => QueryMatch::from(m), - _ => unreachable!(), + .filter_map(|l| match l { + QueryResolutionLine::Match(m) => Some(m), + _ => None, }) .collect::>(); @@ -743,10 +728,10 @@ mod tests { let json_value = json!(false); assert_eq!(json_value, serde_json::to_value(qrl).unwrap()); - let qrl = QueryResolutionLine::Match(btreemap! { - "X".into() => Value::Atom("asdf".into()), - "Y".into() => Value::String("fdsa".into()), - }); + let qrl = QueryResolutionLine::Match(QueryMatch::from(btreemap! { + "X" => Value::Atom("asdf".into()), + "Y" => Value::String("fdsa".into()), + })); let json_value = json!({ "bindings": { "X": { "atom": "asdf" }, diff --git a/tests/scryer_lib/main.rs b/tests/scryer_lib/main.rs index 5bf83de1b..b1ee36bac 100644 --- a/tests/scryer_lib/main.rs +++ b/tests/scryer_lib/main.rs @@ -1,5 +1,4 @@ use scryer_prolog::machine::Machine; -use serde_json; #[test] #[cfg_attr(miri, ignore = "it takes too long to run")]