Compare plain text AST nodes.
This commit is contained in:
parent
037caf369c
commit
777c756a7f
@ -16,6 +16,7 @@ pub(crate) use compare_field::EmacsField;
|
||||
pub(crate) use elisp_fact::ElispFact;
|
||||
pub use sexp::sexp;
|
||||
pub(crate) use sexp::unquote;
|
||||
pub(crate) use sexp::TextWithProperties;
|
||||
pub use sexp::Token;
|
||||
pub(crate) use util::get_emacs_standard_properties;
|
||||
pub(crate) use util::get_property;
|
||||
|
@ -21,7 +21,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::PlainText(original) },
|
||||
{ "TODO".into() },
|
||||
{ "plain-text".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
|
@ -5,9 +5,11 @@ use super::diff::WasmDiffResult;
|
||||
use super::diff::WasmDiffStatus;
|
||||
use crate::compare::get_emacs_standard_properties;
|
||||
use crate::compare::maybe_token_to_usize;
|
||||
use crate::compare::unquote;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::compare::EmacsField;
|
||||
use crate::compare::EmacsStandardProperties;
|
||||
use crate::compare::TextWithProperties;
|
||||
use crate::compare::Token;
|
||||
use crate::wasm::WasmAngleLink;
|
||||
use crate::wasm::WasmAstNode;
|
||||
@ -109,6 +111,9 @@ fn compare_json_value<'b, 's>(
|
||||
{
|
||||
compare_optional_pair(source, e, wasm)
|
||||
}
|
||||
(serde_json::Value::Object(w), Token::TextWithProperties(e)) if is_plain_text(w) => {
|
||||
compare_plain_text(source, e, w)
|
||||
}
|
||||
(serde_json::Value::Null, Token::Atom(_)) => todo!(),
|
||||
(serde_json::Value::Null, Token::List(_)) => todo!(),
|
||||
(serde_json::Value::Null, Token::TextWithProperties(_)) => todo!(),
|
||||
@ -478,6 +483,124 @@ fn compare_optional_pair<'e, 's, 'w>(
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn is_plain_text<'e, 's, 'w>(wasm: &'w serde_json::Map<String, serde_json::Value>) -> bool {
|
||||
if let Some(serde_json::Value::String(node_type)) = wasm.get("ast-node") {
|
||||
node_type == "plain-text"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_plain_text<'e, 's, 'w>(
|
||||
source: &'s str,
|
||||
emacs: &'e TextWithProperties<'s>,
|
||||
wasm: &'w serde_json::Map<String, serde_json::Value>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
let mut result = WasmDiffResult::default();
|
||||
if !is_plain_text(wasm) {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"AST node type mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs,
|
||||
wasm = wasm,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
let emacs_text = unquote(emacs.text)?;
|
||||
let wasm_standard_properties = wasm
|
||||
.get("standard-properties")
|
||||
.ok_or(r#"Wasm AST nodes should have a "standard-properties" attribute."#)?
|
||||
.as_object()
|
||||
.ok_or(r#"Wasm ast node "standard-properties" attribute should be an object."#)?;
|
||||
let wasm_begin = {
|
||||
if let Some(serde_json::Value::Number(begin)) = wasm_standard_properties.get("begin") {
|
||||
begin
|
||||
.as_u64()
|
||||
.map(|w| w as usize)
|
||||
.ok_or("Begin should be a number.")?
|
||||
} else {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"AST node type mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs,
|
||||
wasm = wasm,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
};
|
||||
let wasm_end = {
|
||||
if let Some(serde_json::Value::Number(end)) = wasm_standard_properties.get("end") {
|
||||
end.as_u64()
|
||||
.map(|w| w as usize)
|
||||
.ok_or("End should be a number.")?
|
||||
} else {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"AST node type mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs,
|
||||
wasm = wasm,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
};
|
||||
let wasm_text: String = source
|
||||
.chars()
|
||||
.skip(wasm_begin - 1)
|
||||
.take(wasm_end - wasm_begin)
|
||||
.collect();
|
||||
if wasm_text != emacs_text {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Text mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs_text,
|
||||
wasm = wasm_text,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
let emacs_start = emacs
|
||||
.properties
|
||||
.first()
|
||||
.map(|t| t.as_atom())
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
if emacs_start != Some("0") {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Text should start at offset 0. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs,
|
||||
wasm = wasm,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
let emacs_end = emacs
|
||||
.properties
|
||||
.get(1)
|
||||
.map(|t| t.as_atom())
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
if emacs_end != Some((wasm_end - wasm_begin).to_string().as_str()) {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Text end mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs_end,
|
||||
wasm = wasm_end - wasm_begin,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub fn old_wasm_compare_document<'b, 's, 'p>(
|
||||
// source: &'s str,
|
||||
// emacs: &'b Token<'s>,
|
||||
|
Loading…
Reference in New Issue
Block a user