1use crate::{MarkdownExt, Share};
2use equt_md_frontmatter::FrontMatter;
3use std::cell::RefCell;
4
5enum LinkState {
6 Front,
7 Back,
8}
9
10#[derive(new)]
17pub struct Link<A, B> {
18 frontmatter: Share<RefCell<Option<FrontMatter>>>,
19 a: A,
20 b: B,
21
22 #[new(value = "LinkState::Front")]
23 state: LinkState,
24}
25
26impl<A, B, T> MarkdownExt<T> for Link<A, B>
27where
28 A: Iterator<Item = T>,
29 B: Iterator<Item = T>,
30{
31 fn frontmatter(&mut self) -> &mut Share<RefCell<Option<FrontMatter>>> {
32 &mut self.frontmatter
33 }
34}
35
36impl<A, B, T> Iterator for Link<A, B>
37where
38 A: Iterator<Item = T>,
39 B: Iterator<Item = T>,
40{
41 type Item = T;
42
43 fn next(&mut self) -> Option<Self::Item> {
44 match self.state {
45 LinkState::Front => match self.a.next() {
46 node @ Some(_) => node,
47 None => {
48 self.state = LinkState::Back;
49 self.b.next()
50 }
51 },
52 LinkState::Back => self.b.next(),
53 }
54 }
55}
56
57#[cfg(test)]
58mod test {
59 use super::*;
60 use std::rc::Rc;
61
62 struct TestIter {
63 frontmatter: Share<RefCell<Option<FrontMatter>>>,
64 range: std::ops::Range<u8>,
65 }
66
67 impl From<std::ops::Range<u8>> for TestIter {
68 fn from(r: std::ops::Range<u8>) -> Self {
69 Self {
70 frontmatter: Rc::new(RefCell::new(None)).into(),
71 range: r,
72 }
73 }
74 }
75
76 impl Iterator for TestIter {
77 type Item = u8;
78
79 fn next(&mut self) -> Option<Self::Item> {
80 self.range.next()
81 }
82 }
83
84 impl MarkdownExt<u8> for TestIter {
85 fn frontmatter(&mut self) -> &mut Share<RefCell<Option<FrontMatter>>> {
86 &mut self.frontmatter
87 }
88 }
89
90 #[test]
91 fn iter() {
92 assert_eq!(
93 Link::new(
94 Rc::new(RefCell::new(None)).into(),
95 TestIter::from(1..4),
96 TestIter::from(4..7),
97 )
98 .collect::<Vec<_>>(),
99 (1..7).collect::<Vec<_>>()
100 );
101 }
102}