Implement src block.
Some checks failed
clippy Build clippy has failed
rust-foreign-document-test Build rust-foreign-document-test has succeeded
rust-build Build rust-build has failed
rust-test Build rust-test has failed

This commit is contained in:
Tom Alexander 2023-12-30 17:09:12 -05:00
parent b4fcc6500b
commit 172d72aa46
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 160 additions and 2 deletions

View File

@ -6,13 +6,55 @@ use super::macros::to_wasm;
use super::to_wasm::ToWasm;
use super::AdditionalProperties;
use crate::compare::ElispFact;
use crate::types::CharOffsetInLine;
use crate::types::GetAffiliatedKeywords;
use crate::types::LineNumber;
use crate::types::RetainLabels;
use crate::types::SrcBlock;
use crate::types::SwitchNumberLines;
use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize, Deserialize)]
pub struct WasmSrcBlock {
#[serde(flatten)]
pub(crate) additional_properties: AdditionalProperties,
pub(crate) language: Option<String>,
pub(crate) value: String,
pub(crate) switches: Option<String>,
pub(crate) parameters: Option<String>,
#[serde(rename = "number-lines")]
pub(crate) number_lines: Option<WasmNumberLinesWrapper>,
#[serde(rename = "preserve-indent")]
pub(crate) preserve_indent: Option<CharOffsetInLine>,
#[serde(rename = "retain-labels")]
pub(crate) retain_labels: WasmRetainLabels,
#[serde(rename = "use-labels")]
pub(crate) use_labels: bool,
#[serde(rename = "label-fmt")]
pub(crate) label_format: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
enum WasmRetainLabels {
YesNo(bool),
Keep(CharOffsetInLine),
}
#[derive(Debug, Serialize, Deserialize)]
enum WasmNumberLines {
#[serde(rename = "new")]
New(LineNumber),
#[serde(rename = "continued")]
continued(LineNumber),
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename = "number-lines")]
#[serde(tag = "number-lines")]
struct WasmNumberLinesWrapper {
#[serde(flatten)]
inner: WasmNumberLines,
}
to_wasm!(
@ -21,12 +63,37 @@ to_wasm!(
original,
wasm_context,
{ WasmAstNode::SrcBlock(original) },
{ "TODO".into() },
{ "src-block".into() },
{
let additional_properties = original
.get_affiliated_keywords()
.to_wasm(wasm_context.clone())?;
Ok((
Vec::new(),
WasmSrcBlock {
additional_properties: AdditionalProperties::default(),
additional_properties,
language: original.language.map(|s| s.to_owned()),
value: original.value.to_owned(),
switches: original.switches.map(|s| s.to_owned()),
parameters: original.parameters.map(|s| s.to_owned()),
number_lines: match original.number_lines {
None => None,
Some(SwitchNumberLines::New(n)) => Some(WasmNumberLinesWrapper {
inner: WasmNumberLines::New(n),
}),
Some(SwitchNumberLines::Continued(n)) => Some(WasmNumberLinesWrapper {
inner: WasmNumberLines::continued(n),
}),
},
preserve_indent: original.preserve_indent,
retain_labels: match original.retain_labels {
RetainLabels::No => WasmRetainLabels::YesNo(false),
RetainLabels::Yes => WasmRetainLabels::YesNo(true),
RetainLabels::Keep(n) => WasmRetainLabels::Keep(n),
},
use_labels: original.use_labels,
label_format: original.label_format.map(|s| s.to_owned()),
},
))
}

View File

@ -54,6 +54,10 @@ fn compare_json_value<'b, 's>(
// We hit an object tree additional property.
compare_object_tree(source, el, wasm)
}
(serde_json::Value::Object(wasm), Token::List(el)) if wasm.contains_key("number-lines") => {
// We hit an object tree additional property.
compare_number_lines(source, el, wasm)
}
(serde_json::Value::Object(w), Token::TextWithProperties(e)) if is_plain_text(w) => {
compare_plain_text(source, e, w)
}
@ -628,6 +632,93 @@ fn compare_object_tree<'e, 's, 'w>(
Ok(result)
}
fn compare_number_lines<'e, 's, 'w>(
source: &'s str,
emacs: &'e Vec<Token<'s>>,
wasm: &'w serde_json::Map<String, serde_json::Value>,
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
let mut result = WasmDiffResult::default();
let mut emacs_iter = emacs.iter();
let emacs_directive = emacs_iter
.next()
.ok_or("Emacs number lines should have 3 children.")?
.as_atom()?;
let emacs_number: i64 = emacs_iter
.skip(1)
.next()
.ok_or("Emacs number lines should have 3 children.")?
.as_atom()?
.parse()?;
if wasm.contains_key("new") {
let wasm_number = wasm
.get("new")
.ok_or(r#"Wasm number lines should have a "new" attribute."#)?
.as_i64()
.ok_or(r#"Wasm number lines "new" attribute should be a number."#)?;
if emacs_directive != "new" {
result.status.push(WasmDiffStatus::Bad(
format!(
"Number lines directive mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
emacs = emacs_directive,
wasm = "new"
)
.into(),
));
return Ok(result);
}
if emacs_number != wasm_number {
result.status.push(WasmDiffStatus::Bad(
format!(
"Number lines number mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
emacs = emacs_number,
wasm = wasm_number
)
.into(),
));
return Ok(result);
}
} else if wasm.contains_key("continued") {
let wasm_number = wasm
.get("continued")
.ok_or(r#"Wasm number lines should have a "continued" attribute."#)?
.as_i64()
.ok_or(r#"Wasm number lines "continued" attribute should be a number."#)?;
if emacs_directive != "continued" {
result.status.push(WasmDiffStatus::Bad(
format!(
"Number lines directive mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
emacs = emacs_directive,
wasm = "continued"
)
.into(),
));
return Ok(result);
}
if emacs_number != wasm_number {
result.status.push(WasmDiffStatus::Bad(
format!(
"Number lines number mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
emacs = emacs_number,
wasm = wasm_number
)
.into(),
));
return Ok(result);
}
} else {
result.status.push(WasmDiffStatus::Bad(
format!(
"Unrecognized number lines directive. Wasm=({wasm:?}).",
wasm = wasm
)
.into(),
));
return Ok(result);
}
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"