emacs_org_link_parser/
lib.rs1#[derive(Debug, PartialEq, Eq)]
24pub struct Link {
25 pub link: Option<String>,
26 pub description: Option<String>,
27}
28
29pub fn parse_line(line: &str) -> Vec<Link> {
30 let mut link_begin: Option<usize> = None;
31 let mut link_end: Option<usize> = None;
32
33 let mut line_links: Vec<Link> = Vec::new();
34
35 for (index, character) in line.chars().enumerate() {
36 if character == '[' && line.chars().nth(index-1) == Some('[') {
37 link_begin = Some(index+1);
38 } else if character == ']' && line.chars().nth(index-1) == Some(']') {
39 link_end = Some(index-1);
40 }
41
42 if let Some(begin) = link_begin {
43 if let Some(end) = link_end {
44 let text: Vec<String> = line[begin..end].to_string()
45 .split("][")
46 .map(|x| x.to_string())
47 .collect();
48 let mut text = text.into_iter();
49
50 line_links.push(Link {
51 link: text.next(),
52 description: text.next(),
53 });
54 link_begin = None;
55 link_end = None;
56 }
57 }
58 }
59
60 line_links
61}
62
63#[cfg(test)]
64mod tests {
65 use super::{Link, parse_line};
66
67 #[test]
68 fn correctly_parsed() {
69 let line_to_parse = "*** [[#examp_3le][p3]] dumplings, [[www.best-sauce.com][p34]] [[#anothr][pretty54]] [[alonelink]]";
70
71 let expected_output: Vec<Link> = vec![Link { link: Some("#examp_3le".to_string()), description: Some("p3".to_string()) }, Link { link: Some("www.best-sauce.com".to_string()), description: Some("p34".to_string()) }, Link { link: Some("#anothr".to_string()), description: Some("pretty54".to_string()) }, Link { link: Some("alonelink".to_string()), description: None }];
72
73 assert_eq!(parse_line(line_to_parse), expected_output);
74 }
75}