Implement headline.
This commit is contained in:
parent
fa31b001f4
commit
c0e879dc1e
@ -5,14 +5,39 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use super::AdditionalPropertyValue;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Heading;
|
||||
use crate::types::HeadlineLevel;
|
||||
use crate::types::PriorityCookie;
|
||||
use crate::types::TodoKeywordType;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmHeadline {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) level: HeadlineLevel,
|
||||
pub(crate) tags: Vec<String>,
|
||||
#[serde(rename = "todo-keyword")]
|
||||
pub(crate) todo_keyword: Option<String>,
|
||||
#[serde(rename = "todo-type")]
|
||||
pub(crate) todo_type: Option<String>,
|
||||
pub(crate) title: Vec<WasmAstNode>,
|
||||
pub(crate) priority: Option<PriorityCookie>,
|
||||
#[serde(rename = "archivedp")]
|
||||
pub(crate) is_archived: bool,
|
||||
#[serde(rename = "commentedp")]
|
||||
pub(crate) is_comment: bool,
|
||||
#[serde(rename = "raw-value")]
|
||||
pub(crate) raw_value: String,
|
||||
#[serde(rename = "footnote-section-p")]
|
||||
pub(crate) is_footnote_section: bool,
|
||||
pub(crate) scheduled: Option<Box<WasmAstNode>>,
|
||||
pub(crate) deadline: Option<Box<WasmAstNode>>,
|
||||
pub(crate) closed: Option<Box<WasmAstNode>>,
|
||||
#[serde(rename = "pre-blank")]
|
||||
pub(crate) pre_blank: usize,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@ -21,8 +46,18 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Headline(original) },
|
||||
{ "TODO".into() },
|
||||
{ "headline".into() },
|
||||
{
|
||||
let mut additional_properties = AdditionalProperties::default();
|
||||
for (name, val) in original.get_additional_properties().map(|node_property| {
|
||||
(
|
||||
node_property.property_name.to_uppercase(),
|
||||
AdditionalPropertyValue::SingleString(node_property.value.unwrap_or("").to_owned()),
|
||||
)
|
||||
}) {
|
||||
additional_properties.properties.insert(name, val);
|
||||
}
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@ -36,7 +71,65 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmHeadline {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
level: original.level,
|
||||
tags: original.tags.iter().map(|tag| (*tag).to_owned()).collect(),
|
||||
todo_keyword: original
|
||||
.todo_keyword
|
||||
.as_ref()
|
||||
.map(|(_, keyword)| (*keyword).to_owned()),
|
||||
todo_type: original
|
||||
.todo_keyword
|
||||
.as_ref()
|
||||
.map(|(keyword, _)| match keyword {
|
||||
TodoKeywordType::Done => "done".to_owned(),
|
||||
TodoKeywordType::Todo => "todo".to_owned(),
|
||||
}),
|
||||
title: original
|
||||
.title
|
||||
.iter()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
priority: original.priority_cookie,
|
||||
is_archived: original.is_archived,
|
||||
is_comment: original.is_comment,
|
||||
raw_value: original.get_raw_value(),
|
||||
is_footnote_section: original.is_footnote_section,
|
||||
scheduled: original
|
||||
.scheduled
|
||||
.as_ref()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|child| Box::new(child)),
|
||||
deadline: original
|
||||
.deadline
|
||||
.as_ref()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|child| Box::new(child)),
|
||||
closed: original
|
||||
.closed
|
||||
.as_ref()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|child| Box::new(child)),
|
||||
pre_blank: 0,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
@ -58,11 +58,36 @@ fn compare_json_value<'b, 's>(
|
||||
compare_plain_text(source, e, w)
|
||||
}
|
||||
(serde_json::Value::Null, Token::Atom("nil")) => Ok(WasmDiffResult::default()),
|
||||
(serde_json::Value::Bool(false), Token::Atom("nil")) => Ok(WasmDiffResult::default()),
|
||||
(serde_json::Value::Bool(true), Token::Atom(e)) if (*e) != "nil" => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(serde_json::Value::Bool(w), Token::Atom(e)) => {
|
||||
let mut result = WasmDiffResult::default();
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Value mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = e,
|
||||
wasm = w,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
Ok(result)
|
||||
}
|
||||
(serde_json::Value::Number(w), Token::Atom(e)) if w.to_string().as_str() == (*e) => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(serde_json::Value::Array(w), Token::Atom("nil")) if w.is_empty() => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(serde_json::Value::String(w), Token::Atom(e)) if w.as_str() == *e => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(serde_json::Value::Null, Token::Atom(_)) => todo!(),
|
||||
(serde_json::Value::Null, Token::List(_)) => todo!(),
|
||||
(serde_json::Value::Null, Token::TextWithProperties(_)) => todo!(),
|
||||
(serde_json::Value::Null, Token::Vector(_)) => todo!(),
|
||||
(serde_json::Value::Bool(_), Token::Atom(_)) => todo!(),
|
||||
// (serde_json::Value::Bool(_), Token::Atom(_)) => todo!(),
|
||||
(serde_json::Value::Bool(_), Token::List(_)) => todo!(),
|
||||
(serde_json::Value::Bool(_), Token::TextWithProperties(_)) => todo!(),
|
||||
(serde_json::Value::Bool(_), Token::Vector(_)) => todo!(),
|
||||
@ -70,7 +95,19 @@ fn compare_json_value<'b, 's>(
|
||||
(serde_json::Value::Number(_), Token::List(_)) => todo!(),
|
||||
(serde_json::Value::Number(_), Token::TextWithProperties(_)) => todo!(),
|
||||
(serde_json::Value::Number(_), Token::Vector(_)) => todo!(),
|
||||
(serde_json::Value::String(_), Token::Atom(_)) => todo!(),
|
||||
// (serde_json::Value::String(_), Token::Atom(_)) => todo!(),
|
||||
(serde_json::Value::String(w), Token::Atom(e)) => {
|
||||
let mut result = WasmDiffResult::default();
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Value mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = e,
|
||||
wasm = w,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
Ok(result)
|
||||
}
|
||||
(serde_json::Value::String(_), Token::List(_)) => todo!(),
|
||||
(serde_json::Value::String(_), Token::TextWithProperties(_)) => todo!(),
|
||||
(serde_json::Value::String(_), Token::Vector(_)) => todo!(),
|
||||
@ -85,6 +122,31 @@ fn compare_json_value<'b, 's>(
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_optional_json_value<'b, 's>(
|
||||
source: &'s str,
|
||||
emacs: Option<&'b Token<'s>>,
|
||||
wasm: Option<&serde_json::Value>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
match (emacs, wasm) {
|
||||
(None, None) | (None, Some(serde_json::Value::Null)) | (Some(Token::Atom("nil")), None) => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(Some(e), Some(w)) => compare_json_value(source, e, w),
|
||||
_ => Ok(WasmDiffResult {
|
||||
status: vec![WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Nullness mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs,
|
||||
wasm = wasm
|
||||
)
|
||||
.into(),
|
||||
)],
|
||||
children: Vec::new(),
|
||||
name: "".into(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_ast_node<'e, 's, 'w>(
|
||||
source: &'s str,
|
||||
emacs: &'e Vec<Token<'s>>,
|
||||
@ -137,12 +199,21 @@ fn compare_ast_node<'e, 's, 'w>(
|
||||
.keys()
|
||||
.map(|s| (*s).to_owned())
|
||||
.collect();
|
||||
// wasm_attributes_map.iter().filter_map(|(k,v)| if matches!(v, serde_json::Value::Null) {None} else {Some(k)}).map(wasm_key_to_emacs_key)
|
||||
let wasm_keys: std::collections::BTreeSet<String> =
|
||||
std::iter::once(":standard-properties".to_owned())
|
||||
.chain(wasm_attributes_map.keys().map(wasm_key_to_emacs_key))
|
||||
.collect();
|
||||
let emacs_only_attributes: Vec<&String> = emacs_keys.difference(&wasm_keys).collect();
|
||||
let wasm_only_attributes: Vec<&String> = wasm_keys.difference(&emacs_keys).collect();
|
||||
let wasm_only_attributes: Vec<&String> = wasm_keys
|
||||
.difference(&emacs_keys)
|
||||
.filter(|attribute| {
|
||||
emacs_attributes_map
|
||||
.get(attribute.as_str())
|
||||
.map(|token| !matches!(token, Token::Atom("nil")))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.collect();
|
||||
if !emacs_only_attributes.is_empty() {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
@ -180,14 +251,10 @@ fn compare_ast_node<'e, 's, 'w>(
|
||||
for attribute_name in wasm_attributes_map.keys() {
|
||||
let mut layer = WasmDiffResult::default();
|
||||
layer.name = Cow::Owned(attribute_name.clone());
|
||||
let wasm_attribute_value = wasm_attributes_map
|
||||
.get(attribute_name)
|
||||
.ok_or("Key should exist in both wasm and elisp at this point.")?;
|
||||
let wasm_attribute_value = wasm_attributes_map.get(attribute_name);
|
||||
let emacs_key = wasm_key_to_emacs_key(attribute_name);
|
||||
let emacs_attribute_value = *emacs_attributes_map
|
||||
.get(emacs_key.as_str())
|
||||
.ok_or("Key should exist in both wasm and elisp at this point.")?;
|
||||
layer.extend(compare_json_value(
|
||||
let emacs_attribute_value = emacs_attributes_map.get(emacs_key.as_str()).map(|e| *e);
|
||||
layer.extend(compare_optional_json_value(
|
||||
source,
|
||||
emacs_attribute_value,
|
||||
wasm_attribute_value,
|
||||
|
Loading…
Reference in New Issue
Block a user