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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander