use super::super::prelude::*;
use super::mapping::get_block_rule_with_name;
pub const RULE_BLOCK: Rule = Rule {
name: "block",
try_consume_fn: block_regular,
};
pub const RULE_BLOCK_SPECIAL: Rule = Rule {
name: "block-special",
try_consume_fn: block_special,
};
pub const RULE_BLOCK_SKIP: Rule = Rule {
name: "block-skip",
try_consume_fn: block_skip,
};
fn block_regular<'r, 't>(
log: &slog::Logger,
parser: &mut Parser<'r, 't>,
) -> ParseResult<'r, 't, Elements<'t>> {
trace!(log, "Trying to process a block");
parse_block(log, parser, false)
}
fn block_special<'r, 't>(
log: &slog::Logger,
parser: &mut Parser<'r, 't>,
) -> ParseResult<'r, 't, Elements<'t>> {
trace!(log, "Trying to process a block (with special)");
parse_block(log, parser, true)
}
fn block_skip<'r, 't>(
log: &slog::Logger,
parser: &mut Parser<'r, 't>,
) -> ParseResult<'r, 't, Elements<'t>> {
trace!(
log,
"Trying to see if we skip a newline due to upcoming block",
);
assert_eq!(
parser.current().token,
Token::LineBreak,
"Trying to skip because block, but current is not line break",
);
let current = parser.step()?;
let result = parser.evaluate_fn(|parser| {
if current.token != Token::LeftBlock && current.token != Token::LeftBlockSpecial {
return Ok(false);
}
let (name, _) = parser.get_block_name(false)?;
match get_block_rule_with_name(name) {
Some(block_rule) => Ok(block_rule.accepts_newlines),
None => Ok(false),
}
});
if result {
ok!(Elements::None)
} else {
Err(parser.make_warn(ParseWarningKind::RuleFailed))
}
}
fn parse_block<'r, 't>(
log: &slog::Logger,
parser: &mut Parser<'r, 't>,
special: bool,
) -> ParseResult<'r, 't, Elements<'t>>
where
'r: 't,
{
debug!(
log,
"Trying to process a block";
"special" => special,
);
parser.set_rule(if special {
RULE_BLOCK_SPECIAL
} else {
RULE_BLOCK
});
parser.get_optional_space()?;
let (name, in_head) = parser.get_block_name(special)?;
trace!(log, "Got block name"; "name" => name, "in-head" => in_head);
let block = match get_block_rule_with_name(name) {
Some(block) => block,
None => return Err(parser.make_warn(ParseWarningKind::NoSuchBlock)),
};
parser.set_block(block);
if !block.accepts_special && special {
return Err(parser.make_warn(ParseWarningKind::InvalidSpecialBlock));
}
parser.get_optional_space()?;
(block.parse_fn)(log, parser, name, special, in_head)
}