Compare commits
No commits in common. "dd009498dddfc91596c048393a8a455355265179" and "3f707149e3aff6ee35c534e498ff726fb1a0db0c" have entirely different histories.
dd009498dd
...
3f707149e3
@ -1,7 +0,0 @@
|
|||||||
{{{foo}}}
|
|
||||||
|
|
||||||
{{{fo\o}}}
|
|
||||||
|
|
||||||
{{{foo(b\ar)}}}
|
|
||||||
|
|
||||||
{{{foo(b\,r)}}}
|
|
@ -1,4 +0,0 @@
|
|||||||
{{{foo(bar baz)}}}
|
|
||||||
|
|
||||||
{{{foo(bar
|
|
||||||
baz)}}}
|
|
@ -1,7 +1,6 @@
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use super::diff::DiffStatus;
|
use super::diff::DiffStatus;
|
||||||
use super::sexp::unquote;
|
|
||||||
use super::sexp::Token;
|
use super::sexp::Token;
|
||||||
use super::util::get_property;
|
use super::util::get_property;
|
||||||
use super::util::get_property_quoted_string;
|
use super::util::get_property_quoted_string;
|
||||||
@ -103,59 +102,3 @@ pub(crate) fn compare_property_unquoted_atom<'b, 's, 'x, R, RG: Fn(R) -> Option<
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compare_property_list_of_quoted_string<
|
|
||||||
'b,
|
|
||||||
's,
|
|
||||||
'x,
|
|
||||||
R,
|
|
||||||
RV: AsRef<str> + std::fmt::Debug,
|
|
||||||
RI: Iterator<Item = RV>,
|
|
||||||
RG: Fn(R) -> Option<RI>,
|
|
||||||
>(
|
|
||||||
emacs: &'b Token<'s>,
|
|
||||||
rust_node: R,
|
|
||||||
emacs_field: &'x str,
|
|
||||||
rust_value_getter: RG,
|
|
||||||
) -> Result<Option<(DiffStatus, Option<String>)>, Box<dyn std::error::Error>> {
|
|
||||||
let value = get_property(emacs, emacs_field)?
|
|
||||||
.map(Token::as_list)
|
|
||||||
.map_or(Ok(None), |r| r.map(Some))?;
|
|
||||||
let rust_value = rust_value_getter(rust_node);
|
|
||||||
// TODO: Seems we are needlessly coverting to a vec here.
|
|
||||||
let rust_value: Option<Vec<RV>> = rust_value.map(|it| it.collect());
|
|
||||||
match (value, &rust_value) {
|
|
||||||
(None, None) => {}
|
|
||||||
(None, Some(_)) | (Some(_), None) => {
|
|
||||||
let this_status = DiffStatus::Bad;
|
|
||||||
let message = Some(format!(
|
|
||||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
emacs_field, value, rust_value
|
|
||||||
));
|
|
||||||
return Ok(Some((this_status, message)));
|
|
||||||
}
|
|
||||||
(Some(el), Some(rl)) if el.len() != rl.len() => {
|
|
||||||
let this_status = DiffStatus::Bad;
|
|
||||||
let message = Some(format!(
|
|
||||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
emacs_field, value, rust_value
|
|
||||||
));
|
|
||||||
return Ok(Some((this_status, message)));
|
|
||||||
}
|
|
||||||
(Some(el), Some(rl)) => {
|
|
||||||
for (e, r) in el.iter().zip(rl) {
|
|
||||||
let e = unquote(e.as_atom()?)?;
|
|
||||||
let r = r.as_ref();
|
|
||||||
if e != r {
|
|
||||||
let this_status = DiffStatus::Bad;
|
|
||||||
let message = Some(format!(
|
|
||||||
"{} mismatch (emacs != rust) {:?} != {:?}. Full list: {:?} != {:?}",
|
|
||||||
emacs_field, e, r, value, rust_value
|
|
||||||
));
|
|
||||||
return Ok(Some((this_status, message)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
@ -6,7 +6,6 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
use super::compare_field::compare_identity;
|
use super::compare_field::compare_identity;
|
||||||
use super::compare_field::compare_property_always_nil;
|
use super::compare_field::compare_property_always_nil;
|
||||||
use super::compare_field::compare_property_list_of_quoted_string;
|
|
||||||
use super::compare_field::compare_property_quoted_string;
|
use super::compare_field::compare_property_quoted_string;
|
||||||
use super::compare_field::compare_property_unquoted_atom;
|
use super::compare_field::compare_property_unquoted_atom;
|
||||||
use super::elisp_fact::ElispFact;
|
use super::elisp_fact::ElispFact;
|
||||||
@ -3069,35 +3068,10 @@ fn compare_org_macro<'b, 's>(
|
|||||||
emacs: &'b Token<'s>,
|
emacs: &'b Token<'s>,
|
||||||
rust: &'b OrgMacro<'s>,
|
rust: &'b OrgMacro<'s>,
|
||||||
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> {
|
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> {
|
||||||
let mut this_status = DiffStatus::Good;
|
let this_status = DiffStatus::Good;
|
||||||
let mut message = None;
|
let message = None;
|
||||||
|
|
||||||
if let Some((new_status, new_message)) = compare_properties!(
|
// TODO: Compare :key :value :args
|
||||||
emacs,
|
|
||||||
rust,
|
|
||||||
(
|
|
||||||
EmacsField::Required(":key"),
|
|
||||||
|r| Some(r.macro_name),
|
|
||||||
compare_property_quoted_string
|
|
||||||
),
|
|
||||||
(
|
|
||||||
EmacsField::Required(":value"),
|
|
||||||
|r| Some(r.macro_value),
|
|
||||||
compare_property_quoted_string
|
|
||||||
),
|
|
||||||
(
|
|
||||||
EmacsField::Required(":args"),
|
|
||||||
|r| if r.macro_args.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(r.get_macro_args())
|
|
||||||
},
|
|
||||||
compare_property_list_of_quoted_string
|
|
||||||
)
|
|
||||||
)? {
|
|
||||||
this_status = new_status;
|
|
||||||
message = new_message;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(DiffResult {
|
Ok(DiffResult {
|
||||||
status: this_status,
|
status: this_status,
|
||||||
|
@ -26,7 +26,6 @@ pub(crate) fn org_macro<'b, 'g, 'r, 's>(
|
|||||||
let (remaining, macro_name) = org_macro_name(context, remaining)?;
|
let (remaining, macro_name) = org_macro_name(context, remaining)?;
|
||||||
let (remaining, macro_args) = opt(parser_with_context!(org_macro_args)(context))(remaining)?;
|
let (remaining, macro_args) = opt(parser_with_context!(org_macro_args)(context))(remaining)?;
|
||||||
let (remaining, _) = tag("}}}")(remaining)?;
|
let (remaining, _) = tag("}}}")(remaining)?;
|
||||||
let macro_value = get_consumed(input, remaining);
|
|
||||||
let (remaining, _trailing_whitespace) =
|
let (remaining, _trailing_whitespace) =
|
||||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
|
|
||||||
@ -41,7 +40,6 @@ pub(crate) fn org_macro<'b, 'g, 'r, 's>(
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|arg| arg.into())
|
.map(|arg| arg.into())
|
||||||
.collect(),
|
.collect(),
|
||||||
macro_value: Into::<&str>::into(macro_value),
|
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use super::util::coalesce_whitespace_escaped;
|
|
||||||
use super::util::coalesce_whitespace_if_line_break;
|
use super::util::coalesce_whitespace_if_line_break;
|
||||||
use super::util::remove_line_break;
|
use super::util::remove_line_break;
|
||||||
use super::util::remove_whitespace_if_line_break;
|
use super::util::remove_whitespace_if_line_break;
|
||||||
@ -150,11 +149,7 @@ pub struct AngleLink<'s> {
|
|||||||
pub struct OrgMacro<'s> {
|
pub struct OrgMacro<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub macro_name: &'s str,
|
pub macro_name: &'s str,
|
||||||
/// The macro args from the source.
|
|
||||||
///
|
|
||||||
/// This does not take into account the post-processing that you would get from the upstream emacs org-mode AST. Use `get_macro_args` for an equivalent value.
|
|
||||||
pub macro_args: Vec<&'s str>,
|
pub macro_args: Vec<&'s str>,
|
||||||
pub macro_value: &'s str,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -737,11 +732,3 @@ impl<'s> AngleLink<'s> {
|
|||||||
self.search_option.map(remove_whitespace_if_line_break)
|
self.search_option.map(remove_whitespace_if_line_break)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> OrgMacro<'s> {
|
|
||||||
pub fn get_macro_args<'b>(&'b self) -> impl Iterator<Item = Cow<'s, str>> + 'b {
|
|
||||||
self.macro_args
|
|
||||||
.iter()
|
|
||||||
.map(|arg| coalesce_whitespace_escaped('\\', |c| ",".contains(c))(*arg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -197,316 +197,3 @@ enum CoalesceWhitespaceIfLineBreakState {
|
|||||||
ret: String,
|
ret: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes all whitespace from a string.
|
|
||||||
///
|
|
||||||
/// Example: "foo bar" => "foobar" and "foo \n bar" => "foobar".
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) fn coalesce_whitespace<'s>(input: &'s str) -> Cow<'s, str> {
|
|
||||||
let mut state = CoalesceWhitespace::Normal;
|
|
||||||
for (offset, c) in input.char_indices() {
|
|
||||||
match (&mut state, c) {
|
|
||||||
(CoalesceWhitespace::Normal, ' ' | '\t' | '\r' | '\n') => {
|
|
||||||
let mut ret = String::with_capacity(input.len());
|
|
||||||
ret.push_str(&input[..offset]);
|
|
||||||
ret.push(' ');
|
|
||||||
state = CoalesceWhitespace::HasWhitespace {
|
|
||||||
in_whitespace: true,
|
|
||||||
ret,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
(CoalesceWhitespace::Normal, _) => {}
|
|
||||||
(
|
|
||||||
CoalesceWhitespace::HasWhitespace { in_whitespace, ret },
|
|
||||||
' ' | '\t' | '\r' | '\n',
|
|
||||||
) => {
|
|
||||||
if !*in_whitespace {
|
|
||||||
*in_whitespace = true;
|
|
||||||
ret.push(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(CoalesceWhitespace::HasWhitespace { in_whitespace, ret }, _) => {
|
|
||||||
*in_whitespace = false;
|
|
||||||
ret.push(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match state {
|
|
||||||
CoalesceWhitespace::Normal => Cow::Borrowed(input),
|
|
||||||
CoalesceWhitespace::HasWhitespace {
|
|
||||||
in_whitespace: _,
|
|
||||||
ret,
|
|
||||||
} => Cow::Owned(ret),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CoalesceWhitespace {
|
|
||||||
Normal,
|
|
||||||
HasWhitespace { in_whitespace: bool, ret: String },
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes all whitespace from a string and handle escaping characters.
|
|
||||||
///
|
|
||||||
/// Example: "foo bar" => "foobar" and "foo \n bar" => "foobar" but if the escape character is backslash and comma is an escapable character than "foo\,bar" becomes "foo,bar".
|
|
||||||
pub(crate) fn coalesce_whitespace_escaped<'c, C: Fn(char) -> bool>(
|
|
||||||
escape_character: char,
|
|
||||||
escapable_characters: C,
|
|
||||||
) -> impl for<'s> Fn(&'s str) -> Cow<'s, str> {
|
|
||||||
move |input| impl_coalesce_whitespace_escaped(input, escape_character, &escapable_characters)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn impl_coalesce_whitespace_escaped<'s, C: Fn(char) -> bool>(
|
|
||||||
input: &'s str,
|
|
||||||
escape_character: char,
|
|
||||||
escapable_characters: C,
|
|
||||||
) -> Cow<'s, str> {
|
|
||||||
let mut state = CoalesceWhitespaceEscaped::Normal {
|
|
||||||
in_whitespace: false,
|
|
||||||
};
|
|
||||||
for (offset, c) in input.char_indices() {
|
|
||||||
state = match (state, c) {
|
|
||||||
(CoalesceWhitespaceEscaped::Normal { in_whitespace: _ }, c)
|
|
||||||
if c == escape_character =>
|
|
||||||
{
|
|
||||||
CoalesceWhitespaceEscaped::NormalEscaping {
|
|
||||||
escape_offset: offset,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(CoalesceWhitespaceEscaped::Normal { in_whitespace }, ' ') => {
|
|
||||||
if in_whitespace {
|
|
||||||
let mut ret = String::with_capacity(input.len());
|
|
||||||
ret.push_str(&input[..offset]);
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: true,
|
|
||||||
ret,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
CoalesceWhitespaceEscaped::Normal {
|
|
||||||
in_whitespace: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(CoalesceWhitespaceEscaped::Normal { in_whitespace: _ }, '\t' | '\r' | '\n') => {
|
|
||||||
let mut ret = String::with_capacity(input.len());
|
|
||||||
ret.push_str(&input[..offset]);
|
|
||||||
ret.push(' ');
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: true,
|
|
||||||
ret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(CoalesceWhitespaceEscaped::Normal { in_whitespace: _ }, _) => {
|
|
||||||
CoalesceWhitespaceEscaped::Normal {
|
|
||||||
in_whitespace: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(CoalesceWhitespaceEscaped::NormalEscaping { escape_offset }, c)
|
|
||||||
if escapable_characters(c) =>
|
|
||||||
{
|
|
||||||
// We escaped a character so we need mutation
|
|
||||||
let mut ret = String::with_capacity(input.len());
|
|
||||||
ret.push_str(&input[..escape_offset]);
|
|
||||||
ret.push(c);
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: false,
|
|
||||||
ret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(CoalesceWhitespaceEscaped::NormalEscaping { escape_offset: _ }, ' ') => {
|
|
||||||
// We didn't escape the character so continue as normal.
|
|
||||||
CoalesceWhitespaceEscaped::Normal {
|
|
||||||
in_whitespace: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(
|
|
||||||
CoalesceWhitespaceEscaped::NormalEscaping { escape_offset: _ },
|
|
||||||
'\t' | '\r' | '\n',
|
|
||||||
) => {
|
|
||||||
// We didn't escape the character but we hit whitespace anyway.
|
|
||||||
let mut ret = String::with_capacity(input.len());
|
|
||||||
ret.push_str(&input[..offset]);
|
|
||||||
ret.push(' ');
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: true,
|
|
||||||
ret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(CoalesceWhitespaceEscaped::NormalEscaping { escape_offset: _ }, _) => {
|
|
||||||
// We didn't escape the character so continue as normal.
|
|
||||||
CoalesceWhitespaceEscaped::Normal {
|
|
||||||
in_whitespace: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: _,
|
|
||||||
ret,
|
|
||||||
},
|
|
||||||
c,
|
|
||||||
) if c == escape_character => CoalesceWhitespaceEscaped::RequiresMutationEscaping {
|
|
||||||
ret,
|
|
||||||
matched_escape_character: c,
|
|
||||||
},
|
|
||||||
(
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
mut in_whitespace,
|
|
||||||
mut ret,
|
|
||||||
},
|
|
||||||
' ' | '\t' | '\r' | '\n',
|
|
||||||
) => {
|
|
||||||
if !in_whitespace {
|
|
||||||
in_whitespace = true;
|
|
||||||
ret.push(' ');
|
|
||||||
}
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation { in_whitespace, ret }
|
|
||||||
}
|
|
||||||
(
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: _,
|
|
||||||
mut ret,
|
|
||||||
},
|
|
||||||
_,
|
|
||||||
) => {
|
|
||||||
ret.push(c);
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: false,
|
|
||||||
ret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutationEscaping {
|
|
||||||
mut ret,
|
|
||||||
matched_escape_character: _,
|
|
||||||
},
|
|
||||||
c,
|
|
||||||
) if escapable_characters(c) => {
|
|
||||||
ret.push(c);
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: false,
|
|
||||||
ret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutationEscaping {
|
|
||||||
mut ret,
|
|
||||||
matched_escape_character: _,
|
|
||||||
},
|
|
||||||
' ' | '\t' | '\r' | '\n',
|
|
||||||
) => {
|
|
||||||
ret.push(' ');
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: true,
|
|
||||||
ret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutationEscaping {
|
|
||||||
mut ret,
|
|
||||||
matched_escape_character,
|
|
||||||
},
|
|
||||||
c,
|
|
||||||
) => {
|
|
||||||
ret.push(matched_escape_character);
|
|
||||||
ret.push(c);
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: false,
|
|
||||||
ret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match state {
|
|
||||||
CoalesceWhitespaceEscaped::Normal { in_whitespace: _ } => Cow::Borrowed(input),
|
|
||||||
CoalesceWhitespaceEscaped::NormalEscaping { escape_offset: _ } => Cow::Borrowed(input),
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutation {
|
|
||||||
in_whitespace: _,
|
|
||||||
ret,
|
|
||||||
} => Cow::Owned(ret),
|
|
||||||
CoalesceWhitespaceEscaped::RequiresMutationEscaping {
|
|
||||||
mut ret,
|
|
||||||
matched_escape_character,
|
|
||||||
} => {
|
|
||||||
ret.push(matched_escape_character);
|
|
||||||
Cow::Owned(ret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CoalesceWhitespaceEscaped {
|
|
||||||
Normal {
|
|
||||||
in_whitespace: bool,
|
|
||||||
},
|
|
||||||
NormalEscaping {
|
|
||||||
escape_offset: usize,
|
|
||||||
},
|
|
||||||
RequiresMutation {
|
|
||||||
in_whitespace: bool,
|
|
||||||
ret: String,
|
|
||||||
},
|
|
||||||
RequiresMutationEscaping {
|
|
||||||
ret: String,
|
|
||||||
matched_escape_character: char,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn coalesce_whitespace_escaped_default() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let input = "foobarbaz";
|
|
||||||
let output = coalesce_whitespace_escaped('&', |c| "".contains(c))(input);
|
|
||||||
assert_eq!(output, "foobarbaz");
|
|
||||||
assert!(matches!(output, Cow::Borrowed(_)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn coalesce_whitespace_escaped_whitespace_single() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let input = "foo bar baz";
|
|
||||||
let output = coalesce_whitespace_escaped('&', |c| "".contains(c))(input);
|
|
||||||
assert_eq!(output, "foo bar baz");
|
|
||||||
assert!(matches!(output, Cow::Borrowed(_)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn coalesce_whitespace_escaped_whitespace_double() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let input = "foo bar baz";
|
|
||||||
let output = coalesce_whitespace_escaped('&', |c| "".contains(c))(input);
|
|
||||||
assert_eq!(output, "foo bar baz");
|
|
||||||
assert!(matches!(output, Cow::Owned(_)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn coalesce_whitespace_escaped_escape_match() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let input = "foo &bar baz";
|
|
||||||
let output = coalesce_whitespace_escaped('&', |c| "b".contains(c))(input);
|
|
||||||
assert_eq!(output, "foo bar baz");
|
|
||||||
assert!(matches!(output, Cow::Owned(_)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn coalesce_whitespace_escaped_escape_mismatch() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let input = "foo b&ar baz";
|
|
||||||
let output = coalesce_whitespace_escaped('&', |c| "b".contains(c))(input);
|
|
||||||
assert_eq!(output, "foo b&ar baz");
|
|
||||||
assert!(matches!(output, Cow::Owned(_)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn coalesce_whitespace_escaped_escape_mismatch_around_whitespace(
|
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let input = "foo& bar &baz";
|
|
||||||
let output = coalesce_whitespace_escaped('&', |c| "z".contains(c))(input);
|
|
||||||
assert_eq!(output, "foo& bar &baz");
|
|
||||||
assert!(matches!(output, Cow::Borrowed(_)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user