#![allow(dead_code)]
#![allow(clippy::type_complexity)]
use crate::parser::Link;
use crate::parser::parse::LABEL_LEN_MAX;
use crate::parser::percent_decode;
use crate::take_until_unbalanced;
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::multispace1;
use nom::{Parser, combinator::*};
use std::borrow::Cow;
const ESCAPABLE: &str = r###"!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"###;
pub fn md_text2dest_link(i: &'_ str) -> nom::IResult<&'_ str, Link<'_>> {
let (i, (te, de, ti)) = md_text2dest(i)?;
Ok((i, Link::Text2Dest(te, de, ti)))
}
pub fn md_text2dest(
i: &'_ str,
) -> nom::IResult<&'_ str, (Cow<'_, str>, Cow<'_, str>, Cow<'_, str>)> {
alt((
nom::sequence::delimited(
tag("<"),
map_parser(
nom::bytes::complete::take_till1(|c: char| {
c.is_ascii_whitespace() || c == '>' || c == '<'
}),
alt((md_absolute_uri, md_email_address)),
),
tag(">"),
),
map(
(md_link_text, md_link_destination_enclosed),
|(a, (b, c))| (a, b, c),
),
))
.parse(i)
}
pub fn md_label2dest_link(i: &'_ str) -> nom::IResult<&'_ str, Link<'_>> {
let (i, (l, d, t)) = md_label2dest(i)?;
Ok((i, Link::Label2Dest(l, d, t)))
}
pub fn md_label2dest(
i: &'_ str,
) -> nom::IResult<&'_ str, (Cow<'_, str>, Cow<'_, str>, Cow<'_, str>)> {
let (i, _) = nom::bytes::complete::take_while_m_n(0, 3, |c| c == ' ')(i)?;
let (i, link_text) = md_link_label(i)?;
let (i, _) = nom::character::complete::char(':')(i)?;
let (i, _) = verify(nom::character::complete::multispace1, |s: &str| {
!s.contains("\n\n")
})
.parse(i)?;
let (i, link_destination) = md_link_destination(i)?;
let (i, link_title) = alt((
md_link_title,
nom::combinator::success(Cow::from("")),
))
.parse(i)?;
let (i, _) = nom::character::complete::space0(i)?;
if !i.is_empty() {
let _ = nom::character::complete::newline(i)?;
}
Ok((i, (link_text, link_destination, link_title)))
}
pub fn md_text2label_link(i: &'_ str) -> nom::IResult<&'_ str, Link<'_>> {
let (i, (t, l)) = md_text2label(i)?;
Ok((i, Link::Text2Label(t, l)))
}
pub fn md_text2label(i: &'_ str) -> nom::IResult<&'_ str, (Cow<'_, str>, Cow<'_, str>)> {
let (i, (link_text, link_label)) = alt((
nom::sequence::pair(md_link_text, md_link_label),
nom::combinator::map(nom::sequence::terminated(md_link_text, tag("[]")), |s| {
(s.clone(), s)
}),
nom::combinator::map(md_link_text, |s| (s.clone(), s)),
))
.parse(i)?;
if !i.is_empty() {
let _ = nom::character::complete::none_of("[(")(i)?;
}
Ok((i, (link_text, link_label)))
}
pub(crate) fn md_link_text(i: &'_ str) -> nom::IResult<&'_ str, Cow<'_, str>> {
nom::combinator::map_parser(
nom::sequence::delimited(tag("["), take_until_unbalanced('[', ']'), tag("]")),
md_escaped_str_transform,
)
.parse(i)
}
fn md_link_label(i: &'_ str) -> nom::IResult<&'_ str, Cow<'_, str>> {
nom::combinator::map_parser(
nom::combinator::verify(
nom::sequence::delimited(
tag("["),
nom::bytes::complete::escaped(
nom::character::complete::none_of("\\[]"),
'\\',
nom::character::complete::one_of(ESCAPABLE),
),
tag("]"),
),
|l: &str| l.len() <= LABEL_LEN_MAX,
),
md_escaped_str_transform,
)
.parse(i)
}
pub(crate) fn md_link_destination(i: &'_ str) -> nom::IResult<&'_ str, Cow<'_, str>> {
nom::combinator::map_parser(md_parse_link_destination, md_escaped_str_transform).parse(i)
}
fn md_parse_link_destination(i: &str) -> nom::IResult<&str, &str> {
alt((
nom::sequence::delimited(
tag("<"),
nom::bytes::complete::escaped(
nom::character::complete::none_of(r#"\<>"#),
'\\',
nom::character::complete::one_of(ESCAPABLE),
),
tag(">"),
),
map(nom::bytes::complete::tag("<>"), |_| ""),
alt((
nom::bytes::complete::is_not(" \t\r\n"),
nom::combinator::success(""),
)),
))
.parse(i)
}
pub(crate) fn md_link_destination_enclosed(
i: &'_ str,
) -> nom::IResult<&'_ str, (Cow<'_, str>, Cow<'_, str>)> {
map_parser(
nom::sequence::delimited(tag("("), take_until_unbalanced('(', ')'), tag(")")),
(
md_link_destination,
alt((
md_link_title,
nom::combinator::success(Cow::from("")),
)),
),
)
.parse(i)
}
fn md_link_title(i: &'_ str) -> nom::IResult<&'_ str, Cow<'_, str>> {
nom::combinator::map_parser(md_parse_link_title, md_escaped_str_transform).parse(i)
}
fn md_parse_link_title(i: &str) -> nom::IResult<&str, &str> {
nom::sequence::preceded(
verify(multispace1, |s: &str| !s.contains("\n\n")),
verify(
alt((
nom::sequence::delimited(tag("("), take_until_unbalanced('(', ')'), tag(")")),
nom::sequence::delimited(
tag("'"),
nom::bytes::complete::escaped(
nom::character::complete::none_of(r#"\'"#),
'\\',
nom::character::complete::one_of(ESCAPABLE),
),
tag("'"),
),
nom::sequence::delimited(
tag("\""),
nom::bytes::complete::escaped(
nom::character::complete::none_of(r#"\""#),
'\\',
nom::character::complete::one_of(ESCAPABLE),
),
tag("\""),
),
)),
|s: &str| !s.contains("\n\n"),
),
)
.parse(i)
}
fn md_escaped_str_transform(i: &'_ str) -> nom::IResult<&'_ str, Cow<'_, str>> {
nom::combinator::map(
nom::bytes::complete::escaped_transform(
nom::bytes::complete::is_not("\\"),
'\\',
nom::character::complete::one_of(ESCAPABLE),
),
|s| if s == i { Cow::from(i) } else { Cow::from(s) },
)
.parse(i)
}
fn md_absolute_uri(
i: &'_ str,
) -> nom::IResult<&'_ str, (Cow<'_, str>, Cow<'_, str>, Cow<'_, str>)> {
let j = i;
map(
all_consuming(nom::sequence::separated_pair(
verify(
nom::bytes::complete::take_till1(|c: char| {
!(c.is_ascii_alphanumeric() || "+.-".contains(c))
}),
|s: &str| s.len() >= 2 && s.len() <= 32,
),
tag(":"),
map_parser(
nom::bytes::complete::take_till1(|c: char| {
c.is_ascii_control() || c.is_ascii_whitespace() || "<>".contains(c)
}),
percent_decode,
),
)),
|(scheme, domain)| {
let uri = if matches!(domain, Cow::Borrowed(..)) {
Cow::Borrowed(j)
} else {
Cow::Owned(format!("{scheme}:{domain}"))
};
(uri.clone(), uri, Cow::from(""))
},
)
.parse(i)
}
fn md_email_address(
i: &'_ str,
) -> nom::IResult<&'_ str, (Cow<'_, str>, Cow<'_, str>, Cow<'_, str>)> {
let j = i;
map(
all_consuming(nom::sequence::separated_pair(
nom::bytes::complete::take_till1(|c: char| {
!(c.is_alphanumeric() || ".!#$%&'*+\\/=?^_`{|}~-".contains(c))
}),
tag("@"),
nom::bytes::complete::take_till1(|c: char| !(c.is_alphanumeric() || ".-".contains(c))),
)),
|(_, _)| {
(
Cow::Borrowed(j),
Cow::Owned(format!("mailto:{}", j.to_owned())),
Cow::Borrowed(""),
)
},
)
.parse(i)
}
#[cfg(test)]
mod tests {
use super::*;
use nom::error::ErrorKind;
#[test]
fn test_md_text2dest() {
assert_eq!(
md_text2dest("[text](url)abc"),
Ok(("abc", (Cow::from("text"), Cow::from("url"), Cow::from(""))))
);
assert_eq!(
md_text2dest("[text[i]](url)abc"),
Ok((
"abc",
(Cow::from("text[i]"), Cow::from("url"), Cow::from(""))
))
);
assert_eq!(
md_text2dest("[text[i]](ur(l))abc"),
Ok((
"abc",
(Cow::from("text[i]"), Cow::from("ur(l)"), Cow::from(""))
))
);
assert_eq!(
md_text2dest("[text(url)"),
Err(nom::Err::Error(nom::error::Error::new("", ErrorKind::Tag)))
);
assert_eq!(
md_text2dest("[text](<url>)abc"),
Ok(("abc", (Cow::from("text"), Cow::from("url"), Cow::from(""))))
);
assert_eq!(
md_text2dest("[text](<url> \"link title\")abc"),
Ok((
"abc",
(Cow::from("text"), Cow::from("url"), Cow::from("link title"))
))
);
assert_eq!(
md_text2dest("[text](url \"link title\")abc"),
Ok((
"abc",
(Cow::from("text"), Cow::from("url"), Cow::from("link title"))
))
);
assert_eq!(
md_text2dest("[](./target.md)abc"),
Ok((
"abc",
(Cow::from(""), Cow::from("./target.md"), Cow::from(""))
))
);
assert_eq!(
md_text2dest("[link]()abc"),
Ok(("abc", (Cow::from("link"), Cow::from(""), Cow::from(""))))
);
assert_eq!(
md_text2dest("[link](<>)abc"),
Ok(("abc", (Cow::from("link"), Cow::from(""), Cow::from(""))))
);
assert_eq!(
md_text2dest("[]()abc"),
Ok(("abc", (Cow::from(""), Cow::from(""), Cow::from(""))))
);
assert_eq!(
md_text2dest("[text]abc"),
Err(nom::Err::Error(nom::error::Error::new(
"abc",
ErrorKind::Tag
)))
);
assert_eq!(
md_text2dest("<a+b+c:d>abc"),
Ok((
"abc",
(Cow::from("a+b+c:d"), Cow::from("a+b+c:d"), Cow::from(""))
))
);
assert_eq!(
md_text2dest("<foo@bar.example.com>abc"),
Ok((
"abc",
(
Cow::from("foo@bar.example.com"),
Cow::from("mailto:foo@bar.example.com"),
Cow::from("")
)
))
);
assert_eq!(
md_text2dest("<foo.example.com>abc"),
Err(nom::Err::Error(nom::error::Error::new(
"<foo.example.com>abc",
ErrorKind::Tag
)))
);
assert_eq!(
md_text2dest(r#"<http://example.com?find=\*>abc"#),
Ok((
"abc",
(
Cow::from(r#"http://example.com?find=\*"#),
Cow::from(r#"http://example.com?find=\*"#),
Cow::from("")
)
))
);
assert_eq!(
md_text2dest(r#"[foo](/bar\* "ti\*tle")abc"#),
Ok((
"abc",
(Cow::from("foo"), Cow::from("/bar*"), Cow::from("ti*tle"))
))
);
}
#[test]
fn test_md_text2label() {
assert_eq!(
md_text2label("[link text][link label]abc"),
Ok(("abc", (Cow::from("link text"), Cow::from("link label"))))
);
assert_eq!(
md_text2label("[link text][]abc"),
Ok(("abc", (Cow::from("link text"), Cow::from("link text"))))
);
assert_eq!(
md_text2label("[link text]abc"),
Ok(("abc", (Cow::from("link text"), Cow::from("link text"))))
);
assert_eq!(
md_text2label("[]abc"),
Ok(("abc", (Cow::from(""), Cow::from(""))))
);
assert_eq!(
md_text2label(""),
Err(nom::Err::Error(nom::error::Error::new("", ErrorKind::Tag)))
);
assert_eq!(
md_text2label("[text]"),
Ok(("", (Cow::from("text"), Cow::from("text"))))
);
assert_eq!(
md_text2label("[text][text]"),
Ok(("", (Cow::from("text"), Cow::from("text"))))
);
assert_eq!(
md_text2label("[text][label url"),
Err(nom::Err::Error(nom::error::Error::new(
"[label url",
ErrorKind::NoneOf
)))
);
assert_eq!(
md_text2label("[text](url)abc"),
Err(nom::Err::Error(nom::error::Error::new(
"(url)abc",
ErrorKind::NoneOf
)))
);
}
#[test]
fn test_md_label2dest() {
assert_eq!(
md_label2dest("[text]: url\nabc"),
Ok((
"\nabc",
(Cow::from("text"), Cow::from("url"), Cow::from(""))
))
);
assert_eq!(
md_label2dest("[text]: url \nabc"),
Ok((
"\nabc",
(Cow::from("text"), Cow::from("url"), Cow::from(""))
))
);
assert_eq!(
md_label2dest("[text]: <url url> \nabc"),
Ok((
"\nabc",
(Cow::from("text"), Cow::from("url url"), Cow::from(""))
))
);
assert_eq!(
md_label2dest("[text]: url \"title\"\nabc"),
Ok((
"\nabc",
(Cow::from("text"), Cow::from("url"), Cow::from("title"))
))
);
assert_eq!(
md_label2dest("[text]: url\n\"title\"\nabc"),
Ok((
"\nabc",
(Cow::from("text"), Cow::from("url"), Cow::from("title"))
))
);
assert_eq!(
md_label2dest(" [text]: url\n\"title\"\nabc"),
Ok((
"\nabc",
(Cow::from("text"), Cow::from("url"), Cow::from("title"))
))
);
assert_eq!(
md_label2dest("abc[text]: url\n\"title\""),
Err(nom::Err::Error(nom::error::Error::new(
"abc[text]: url\n\"title\"",
ErrorKind::Tag
)))
);
assert_eq!(
md_label2dest(" [text]: url\n\"title\" abc"),
Err(nom::Err::Error(nom::error::Error::new(
" [text]: url\n\"title\" abc",
ErrorKind::Tag
)))
);
assert_eq!(
md_label2dest("[text\\[i\\]]: ur(l)url\nabc"),
Ok((
"\nabc",
(Cow::from("text[i]"), Cow::from("ur(l)url"), Cow::from(""))
))
);
assert_eq!(
md_label2dest("[text[i]]: ur(l)(url"),
Err(nom::Err::Error(nom::error::Error::new(
"[i]]: ur(l)(url",
ErrorKind::Tag
)))
);
assert_eq!(
md_label2dest("[text]: \nurl"),
Ok(("", (Cow::from("text"), Cow::from("url"), Cow::from(""))))
);
assert_eq!(
md_label2dest("[text]: \n\nurl"),
Err(nom::Err::Error(nom::error::Error::new(
" \n\nurl",
ErrorKind::Verify
)))
);
assert_eq!(
md_label2dest("[text: url"),
Err(nom::Err::Error(nom::error::Error::new("", ErrorKind::Tag)))
);
assert_eq!(
md_label2dest("[text] url"),
Err(nom::Err::Error(nom::error::Error::new(
" url",
ErrorKind::Char
)))
);
assert_eq!(
md_label2dest("[text]: url \"link title\"\nabc"),
Ok((
"\nabc",
(Cow::from("text"), Cow::from("url"), Cow::from("link title"))
))
);
assert_eq!(
md_label2dest("[text]: url \"link\ntitle\"\nabc"),
Ok((
"\nabc",
(
Cow::from("text"),
Cow::from("url"),
Cow::from("link\ntitle")
)
))
);
assert_eq!(
md_label2dest("[text]: url \"link\ntitle\"abc"),
Err(nom::Err::Error(nom::error::Error::new(
"abc",
ErrorKind::Char
)))
);
assert_eq!(
md_label2dest("[text]:\nurl \"link\ntitle\"\nabc"),
Ok((
"\nabc",
(
Cow::from("text"),
Cow::from("url"),
Cow::from("link\ntitle")
)
))
);
assert_eq!(
md_label2dest("[text]: url \"link\n\ntitle\"\nabc"),
Err(nom::Err::Error(nom::error::Error::new(
"\"link\n\ntitle\"\nabc",
ErrorKind::Char
)))
);
assert_eq!(
md_label2dest("[text]:\n\nurl \"link title\"\nabc"),
Err(nom::Err::Error(nom::error::Error::new(
"\n\nurl \"link title\"\nabc",
ErrorKind::Verify
)))
);
assert_eq!(
md_label2dest(r#"[foo]: /bar\* "ti\*tle""#),
Ok((
"",
(Cow::from("foo"), Cow::from("/bar*"), Cow::from("ti*tle"))
))
);
}
#[test]
fn test_md_link_text() {
assert_eq!(
md_link_text("[text](url)"),
Ok(("(url)", Cow::from("text")))
);
assert_eq!(
md_link_text("[text[i]](url)"),
Ok(("(url)", Cow::from("text[i]")))
);
assert_eq!(
md_link_text(r#"[text\[i\]](url)"#),
Ok(("(url)", Cow::from("text[i]")))
);
assert_eq!(
md_link_text("[text(url)"),
Err(nom::Err::Error(nom::error::Error::new("", ErrorKind::Tag)))
);
assert_eq!(
md_link_text(r#"[te\_xt](url)"#),
Ok(("(url)", Cow::from("te_xt")))
);
}
#[test]
fn test_md_link_label() {
assert_eq!(
md_link_label("[text]: url"),
Ok((": url", Cow::from("text")))
);
assert_eq!(
md_link_label(r#"[text\[i\]]: url"#),
Ok((": url", Cow::from("text[i]")))
);
assert_eq!(
md_link_label("[text: url"),
Err(nom::Err::Error(nom::error::Error::new("", ErrorKind::Tag)))
);
assert_eq!(
md_link_label("[t[ext: url"),
Err(nom::Err::Error(nom::error::Error::new(
"[ext: url",
ErrorKind::Tag
)))
);
}
#[test]
fn test_md_link_destination() {
assert_eq!(
md_link_destination("url abc"),
Ok((" abc", Cow::from("url")))
);
assert_eq!(md_link_destination("url"), Ok(("", Cow::from("url"))));
assert_eq!(
md_link_destination("url\nabc"),
Ok(("\nabc", Cow::from("url")))
);
assert_eq!(
md_link_destination("<url>abc"),
Ok(("abc", Cow::from("url")))
);
assert_eq!(
md_link_destination(r#"<u\<r\>l>abc"#),
Ok(("abc", Cow::from(r#"u<r>l"#)))
);
assert_eq!(
md_link_destination(r#"u\)r\(l abc"#),
Ok((" abc", Cow::from(r#"u)r(l"#)))
);
assert_eq!(
md_link_destination(r#"u(r)l abc"#),
Ok((" abc", Cow::from(r#"u(r)l"#)))
);
assert_eq!(
md_link_destination("u(r)l\nabc"),
Ok(("\nabc", Cow::from(r#"u(r)l"#)))
);
}
#[test]
fn test_md_parse_link_destination() {
assert_eq!(md_parse_link_destination("<url>abc"), Ok(("abc", "url")));
assert_eq!(
md_parse_link_destination(r#"<u\<r\>l>abc"#),
Ok(("abc", r#"u\<r\>l"#))
);
assert_eq!(md_parse_link_destination("<url> abc"), Ok((" abc", "url")));
assert_eq!(
md_parse_link_destination("<url>\nabc"),
Ok(("\nabc", "url"))
);
assert_eq!(
md_parse_link_destination("<url 2>abc"),
Ok(("abc", "url 2"))
);
assert_eq!(md_parse_link_destination("url abc"), Ok((" abc", "url")));
assert_eq!(
md_parse_link_destination("<url(1)> abc"),
Ok((" abc", "url(1)"))
);
assert_eq!(
md_parse_link_destination(r#"<[1a]\[1b\](2a)\(2b\)\<3b\>{4a}\{4b\}> abc"#),
Ok((" abc", r#"[1a]\[1b\](2a)\(2b\)\<3b\>{4a}\{4b\}"#))
);
assert_eq!(
md_parse_link_destination("ur()l abc"),
Ok((" abc", "ur()l"))
);
assert_eq!(
md_parse_link_destination("ur()l\nabc"),
Ok(("\nabc", "ur()l"))
);
assert_eq!(md_parse_link_destination("<>abc"), Ok(("abc", "")));
assert_eq!(md_parse_link_destination("<>\nabc"), Ok(("\nabc", "")));
assert_eq!(md_parse_link_destination("url"), Ok(("", "url")));
assert_eq!(md_parse_link_destination(""), Ok(("", "")));
assert_eq!(md_parse_link_destination("\nabc"), Ok(("\nabc", "")));
}
#[test]
fn test_md_escaped_str_transform() {
assert_eq!(md_escaped_str_transform(""), Ok(("", Cow::from(""))));
assert_eq!(md_escaped_str_transform(" "), Ok(("", Cow::from(" "))));
assert_eq!(
md_escaped_str_transform(r#"abc`:<>abc"#),
Ok(("", Cow::from(r#"abc`:<>abc"#)))
);
assert_eq!(
md_escaped_str_transform(r#"\<\>\\"#),
Ok(("", Cow::from(r#"<>\"#)))
);
assert_eq!(
md_escaped_str_transform(r#"\(\)\\"#),
Ok(("", Cow::from(r#"()\"#)))
);
assert_eq!(
md_escaped_str_transform(
r#"\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~"#
),
Ok(("", Cow::from(r###"!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"###)))
);
}
#[test]
fn test_md_link_title() {
assert_eq!(
md_link_title(" (title)abc"),
Ok(("abc", Cow::from("title")))
);
assert_eq!(
md_link_title(" (ti(t)le)abc"),
Ok(("abc", Cow::from("ti(t)le")))
);
assert_eq!(
md_link_title(r#" (ti\(t\)le)abc"#),
Ok(("abc", Cow::from("ti(t)le")))
);
assert_eq!(
md_link_title(r#" "1\\23\"4\'56"abc"#),
Ok(("abc", Cow::from(r#"1\23"4'56"#)))
);
assert_eq!(
md_link_title(" \"tu\nvwxy\"abc"),
Ok(("abc", Cow::from("tu\nvwxy")))
);
assert_eq!(
md_link_title(" 'tu\nv\\\'wxy'abc"),
Ok(("abc", Cow::from("tu\nv\'wxy")))
);
assert_eq!(
md_link_title(" (ti\n\ntle)abc"),
Err(nom::Err::Error(nom::error::Error::new(
"(ti\n\ntle)abc",
ErrorKind::Verify
)))
);
}
#[test]
fn test_md_parse_link_title() {
assert_eq!(md_parse_link_title(" (title)abc"), Ok(("abc", "title")));
assert_eq!(md_parse_link_title(" (ti(t)le)abc"), Ok(("abc", "ti(t)le")));
assert_eq!(
md_parse_link_title(r#" "1\\23\"4\'56"abc"#),
Ok(("abc", r#"1\\23\"4\'56"#))
);
assert_eq!(
md_parse_link_title(" \"tu\nvwxy\"abc"),
Ok(("abc", "tu\nvwxy"))
);
assert_eq!(
md_parse_link_title(" 'tu\nv\\\'wxy'abc"),
Ok(("abc", "tu\nv\\\'wxy"))
);
assert_eq!(
md_parse_link_title(" (ti\n\ntle)abc"),
Err(nom::Err::Error(nom::error::Error::new(
"(ti\n\ntle)abc",
ErrorKind::Verify
)))
);
}
#[test]
fn test_md_absolute_uri() {
assert_eq!(
md_absolute_uri("http://domain.com").unwrap().1.0,
Cow::Borrowed("http://domain.com")
);
assert_eq!(
md_absolute_uri("http://domain.com").unwrap().1.1,
Cow::Borrowed("http://domain.com")
);
assert_eq!(
md_absolute_uri("scheme:domain").unwrap().1.1,
Cow::Borrowed("scheme:domain")
);
assert_eq!(
md_absolute_uri("scheme:domain abc"),
Err(nom::Err::Error(nom::error::Error::new(
" abc",
ErrorKind::Eof
)))
);
assert_eq!(
md_absolute_uri("h:domain"),
Err(nom::Err::Error(nom::error::Error::new(
"h:domain",
ErrorKind::Verify
)))
);
assert_eq!(
md_absolute_uri("sche&me:domain"),
Err(nom::Err::Error(nom::error::Error::new(
"&me:domain",
ErrorKind::Tag
)))
);
assert_eq!(
md_absolute_uri("scheme+much+too.long......................:uri"),
Err(nom::Err::Error(nom::error::Error::new(
"scheme+much+too.long......................:uri",
ErrorKind::Verify
)))
);
assert_eq!(
md_absolute_uri("httpÜ:domain abc"),
Err(nom::Err::Error(nom::error::Error::new(
"Ü:domain abc",
ErrorKind::Tag
)))
);
assert_eq!(
md_absolute_uri("no colon"),
Err(nom::Err::Error(nom::error::Error::new(
" colon",
ErrorKind::Tag
)))
);
assert_eq!(
md_absolute_uri("scheme:domai>n"),
Err(nom::Err::Error(nom::error::Error::new(
">n",
ErrorKind::Eof
)))
);
let res = md_absolute_uri("scheme:domain").unwrap();
assert!(matches!(res.1.0, Cow::Borrowed(..)));
assert_eq!(res.1.0, Cow::from("scheme:domain"));
let res = md_absolute_uri("scheme:domai%25n").unwrap();
assert!(matches!(res.1.0, Cow::Owned(..)));
assert_eq!(res.1.0, Cow::from("scheme:domai%n"));
}
#[test]
fn test_md_email_address() {
let res = md_email_address("local@domain").unwrap();
assert!(matches!(res.1.0, Cow::Borrowed(..)));
assert!(matches!(res.1.1, Cow::Owned(..)));
assert_eq!(res.1.0, Cow::from("local@domain"));
assert_eq!(res.1.1, Cow::from("mailto:local@domain"));
let res = md_email_address("localÜ@domainÜ").unwrap();
assert!(matches!(res.1.0, Cow::Borrowed(..)));
assert!(matches!(res.1.1, Cow::Owned(..)));
assert_eq!(res.1.0, Cow::from("localÜ@domainÜ"));
assert_eq!(res.1.1, Cow::from("mailto:localÜ@domainÜ"));
let res = md_email_address("lo.cal@domain").unwrap();
assert!(matches!(res.1.0, Cow::Borrowed(..)));
assert!(matches!(res.1.1, Cow::Owned(..)));
assert_eq!(res.1.0, Cow::from("lo.cal@domain"));
assert_eq!(res.1.1, Cow::from("mailto:lo.cal@domain"));
assert_eq!(
md_email_address("lo_cal@do_main"),
Err(nom::Err::Error(nom::error::Error::new(
"_main",
ErrorKind::Eof
)))
);
}
}