org_rust_parser/object/
export_snippet.rs1use crate::constants::{COLON, HYPHEN, NEWLINE};
2use crate::node_pool::NodeID;
3use crate::types::{Cursor, MatchError, ParseOpts, Parseable, Parser, Result};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct ExportSnippet<'a> {
7 pub backend: &'a str,
8 pub contents: &'a str,
9}
10
11impl<'a> Parseable<'a> for ExportSnippet<'a> {
12 fn parse(
13 parser: &mut Parser<'a>,
14 mut cursor: Cursor<'a>,
15 parent: Option<NodeID>,
16 parse_opts: ParseOpts,
17 ) -> Result<NodeID> {
18 let start = cursor.index;
19 cursor.word("@@")?;
20 let backend_match = cursor
21 .fn_until(|chr| chr == COLON || !(chr.is_ascii_alphanumeric() || chr == HYPHEN))?;
22
23 cursor.index = backend_match.end;
24 cursor.word(":")?;
25
26 let start_contents = cursor.index;
27 loop {
28 let pot_match = cursor.fn_until(|chr| chr == b'@' || chr == NEWLINE)?;
29 cursor.index = pot_match.end;
30 match cursor.curr() {
31 b'@' => {
32 if cursor.peek(1)? == b'@' {
33 return Ok(parser.alloc(
34 Self {
35 backend: backend_match.obj,
36 contents: cursor.clamp_backwards(start_contents),
37 },
38 start,
39 cursor.index + 2,
40 parent,
41 ));
42 } else {
43 cursor.next();
44 }
45 }
46 _ => return Err(MatchError::InvalidLogic),
47 }
48 }
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use crate::{expr_in_pool, parse_org, types::Expr};
55
56 use super::*;
57
58 #[test]
59 fn basic_export() {
60 let input = r"
61@@:@@
62";
63
64 let parsed = parse_org(input);
65 let l = expr_in_pool!(parsed, ExportSnippet).unwrap();
66 assert_eq!(
67 l,
68 &ExportSnippet {
69 backend: "",
70 contents: ""
71 }
72 );
73 }
74
75 #[test]
76 fn cool_export() {
77 let input = r"
78@@html:valuesss@@
79";
80 let parsed = parse_org(input);
81 let l = expr_in_pool!(parsed, ExportSnippet).unwrap();
82 assert_eq!(
83 l,
84 &ExportSnippet {
85 backend: "html",
86 contents: "valuesss"
87 }
88 );
89 }
90
91 #[test]
92 fn newline_export_snippet() {
93 let input = r"
94@@html:value
95sss@@
96";
97 let pool = parse_org(input);
98 let parsed = parse_org(input);
99 let l = expr_in_pool!(parsed, ExportSnippet);
100 assert!(l.is_none());
101 }
102
103 #[test]
104 fn at_export_snippet() {
105 let input = r"
106@@html:va@lue sss@@
107";
108 let pool = parse_org(input);
109 let head = pool.pool.iter().find_map(|x| {
110 if let Expr::ExportSnippet(snip) = &x.obj {
111 Some(snip)
112 } else {
113 None
114 }
115 });
116 assert_eq!(
117 head.unwrap(),
118 &ExportSnippet {
119 backend: "html",
120 contents: "va@lue sss"
121 }
122 );
123 }
124}