use super::shared::{opt_span_range, GrammarSpan};
use crate::grammar::inlines as grammar;
use crate::parser::ast::{Node, NodeKind};
use nom::IResult;
pub fn parse_hard_line_break(input: GrammarSpan) -> IResult<GrammarSpan, Node> {
let (rest, _) = grammar::hard_line_break(input)?;
let node = Node {
kind: NodeKind::HardBreak,
span: opt_span_range(input, rest),
children: Vec::new(),
};
Ok((rest, node))
}
pub fn parse_soft_line_break(input: GrammarSpan) -> IResult<GrammarSpan, Node> {
let (rest, _) = grammar::soft_line_break(input)?;
let node = Node {
kind: NodeKind::SoftBreak,
span: opt_span_range(input, rest),
children: Vec::new(),
};
Ok((rest, node))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn smoke_test_parse_hard_line_break_spaces() {
let input = GrammarSpan::new(" \n");
let result = parse_hard_line_break(input);
assert!(
result.is_ok(),
"Failed to parse hard line break with spaces"
);
let (rest, node) = result.unwrap();
assert_eq!(rest.fragment(), &"");
assert!(matches!(node.kind, NodeKind::HardBreak));
assert!(node.children.is_empty());
}
#[test]
fn smoke_test_parse_hard_line_break_backslash() {
let input = GrammarSpan::new("\\\n");
let result = parse_hard_line_break(input);
assert!(
result.is_ok(),
"Failed to parse hard line break with backslash"
);
let (_, node) = result.unwrap();
assert!(matches!(node.kind, NodeKind::HardBreak));
}
#[test]
fn smoke_test_parse_hard_line_break_not_hard() {
let input = GrammarSpan::new("\n");
let result = parse_hard_line_break(input);
assert!(result.is_err(), "Should not parse soft break as hard break");
}
#[test]
fn smoke_test_parse_soft_line_break() {
let input = GrammarSpan::new("\n");
let result = parse_soft_line_break(input);
assert!(result.is_ok(), "Failed to parse soft line break");
let (rest, node) = result.unwrap();
assert_eq!(rest.fragment(), &"");
assert!(matches!(node.kind, NodeKind::SoftBreak));
assert!(node.children.is_empty());
}
#[test]
fn smoke_test_parse_soft_line_break_not_newline() {
let input = GrammarSpan::new("text");
let result = parse_soft_line_break(input);
assert!(
result.is_err(),
"Should not parse non-newline as soft break"
);
}
#[test]
fn smoke_test_parse_hard_line_break_position() {
let input = GrammarSpan::new(" \nmore text");
let result = parse_hard_line_break(input);
assert!(result.is_ok());
let (rest, node) = result.unwrap();
assert_eq!(rest.fragment(), &"more text");
assert!(node.span.is_some(), "Hard break should have position info");
let span = node.span.unwrap();
assert_eq!(span.start.offset, 0);
assert_eq!(span.end.offset, 3); }
#[test]
fn smoke_test_parse_soft_line_break_position() {
let input = GrammarSpan::new("\nmore text");
let result = parse_soft_line_break(input);
assert!(result.is_ok());
let (rest, node) = result.unwrap();
assert_eq!(rest.fragment(), &"more text");
assert!(node.span.is_some(), "Soft break should have position info");
let span = node.span.unwrap();
assert_eq!(span.start.offset, 0);
assert_eq!(span.end.offset, 1); }
}