use super::node::parse_nodes;
use crate::CosyParserExtension;
use crate::ast::{Block, BlockContent};
use winnow::Result as PResult;
use winnow::ascii::{line_ending, till_line_ending};
use winnow::combinator::opt;
use winnow::prelude::*;
use winnow::token::any;
pub fn parse_quote<'s, E>(
input: &mut &'s str,
extension: &'s E,
indent: usize,
) -> PResult<Block<E::Output>>
where
E: CosyParserExtension,
{
let _ = any.parse_next(input)?;
let line_content = till_line_ending.parse_next(input)?;
let _ = opt(line_ending).parse_next(input)?;
let mut span = line_content;
if span.starts_with(' ') {
span = &span[1..];
}
let nodes = parse_nodes(&mut span, extension)?;
Ok(Block {
indent,
content: BlockContent::Quote(nodes),
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::*;
#[test]
fn parse_quote_block() {
let input = "> This is a quote line.\n";
let mut input_stream = input;
let result = parse_quote(&mut input_stream, &(), 0);
assert!(result.is_ok());
let block = result.unwrap();
assert_eq!(block.indent, 0);
assert_eq!(
block.content,
BlockContent::Quote(vec![Node::Text("This is a quote line.".to_string())])
);
}
#[test]
fn parse_quote_no_space() {
let input = ">text without leading space\n";
let mut input_stream = input;
let result = parse_quote(&mut input_stream, &(), 0);
assert!(result.is_ok());
let block = result.unwrap();
assert_eq!(
block.content,
BlockContent::Quote(vec![Node::Text("text without leading space".to_string())])
);
}
#[test]
fn parse_formatted_quote() {
let input = "> [* Bold Quote] and [Linked part]\n";
let mut input_stream = input;
let result = parse_quote(&mut input_stream, &(), 0);
assert!(result.is_ok());
let block = result.unwrap();
assert_eq!(block.indent, 0);
assert_eq!(
block.content,
BlockContent::Quote(vec![
Node::Decoration {
decos: "*".to_string(),
nodes: vec![Node::Text("Bold Quote".to_string())]
},
Node::Text(" and ".to_string()),
Node::Link(Link::Page("Linked part".to_string())),
])
);
}
}