Skip to content

Commit 5b04225

Browse files
authored
feat: visitor pattern for vimdoc (#74)
1 parent 5dba98a commit 5b04225

File tree

23 files changed

+426
-467
lines changed

23 files changed

+426
-467
lines changed

src/lib.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,35 @@ use std::{fmt::Display, str::FromStr};
88

99
use chumsky::prelude::Simple;
1010

11-
use parser::Node;
11+
use parser::{
12+
Alias, Brief, Class, Divider, Field, Func, Module, Node, Param, Return, See, Tag, Type, Usage,
13+
};
1214

1315
use crate::lexer::TagType;
1416

17+
pub trait Visitor {
18+
type R;
19+
type S;
20+
fn module(&self, n: &Module, s: &Self::S) -> Self::R;
21+
fn divider(&self, n: &Divider, s: &Self::S) -> Self::R;
22+
fn brief(&self, n: &Brief, s: &Self::S) -> Self::R;
23+
fn tag(&self, n: &Tag, s: &Self::S) -> Self::R;
24+
fn func(&self, n: &Func, s: &Self::S) -> Self::R;
25+
fn params(&self, n: &[Param], s: &Self::S) -> Self::R;
26+
fn r#returns(&self, n: &[Return], s: &Self::S) -> Self::R;
27+
fn class(&self, n: &Class, s: &Self::S) -> Self::R;
28+
fn fields(&self, n: &[Field], s: &Self::S) -> Self::R;
29+
fn alias(&self, n: &Alias, s: &Self::S) -> Self::R;
30+
fn r#type(&self, n: &Type, s: &Self::S) -> Self::R;
31+
fn toc(&self, n: &str, nodes: &[Node], s: &Self::S) -> Self::R;
32+
fn see(&self, n: &See, s: &Self::S) -> Self::R;
33+
fn usage(&self, n: &Usage, s: &Self::S) -> Self::R;
34+
}
35+
36+
pub trait Accept<T: Visitor> {
37+
fn accept(&self, n: &T, s: &T::S) -> T::R;
38+
}
39+
1540
pub trait Nodes {
1641
fn nodes(&self) -> &Vec<Node>;
1742
}

src/parser/node.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use chumsky::{
66
use crate::{
77
lexer::{Lexer, TagType},
88
parser::{Alias, Brief, Class, Divider, Func, Module, Tag, Type},
9+
Accept, Visitor,
910
};
1011

1112
use super::impl_parse;
@@ -44,6 +45,22 @@ impl_parse!(Node, Option<Self>, {
4445
.or(any().to(None))
4546
});
4647

48+
impl<T: Visitor> Accept<T> for Node {
49+
fn accept(&self, n: &T, s: &T::S) -> T::R {
50+
match self {
51+
Self::Brief(x) => x.accept(n, s),
52+
Self::Tag(x) => x.accept(n, s),
53+
Self::Alias(x) => x.accept(n, s),
54+
Self::Func(x) => x.accept(n, s),
55+
Self::Class(x) => x.accept(n, s),
56+
Self::Type(x) => x.accept(n, s),
57+
Self::Module(x) => x.accept(n, s),
58+
Self::Divider(x) => x.accept(n, s),
59+
_ => unimplemented!(),
60+
}
61+
}
62+
}
63+
4764
impl Node {
4865
fn init() -> impl Parser<TagType, Vec<Node>, Error = Simple<TagType>> {
4966
Node::parse().repeated().flatten()

src/parser/tags/alias.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use chumsky::{prelude::choice, select, Parser};
33
use crate::{
44
lexer::{Member, TagType, Ty},
55
parser::{impl_parse, Prefix},
6+
Accept, Visitor,
67
};
78

89
#[derive(Debug, Clone)]
@@ -43,3 +44,9 @@ impl_parse!(Alias, {
4344
prefix: Prefix::default(),
4445
})
4546
});
47+
48+
impl<T: Visitor> Accept<T> for Alias {
49+
fn accept(&self, n: &T, s: &T::S) -> T::R {
50+
n.alias(self, s)
51+
}
52+
}

src/parser/tags/brief.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use chumsky::{prelude::just, select, Parser};
22

3-
use crate::{lexer::TagType, parser::impl_parse};
3+
use crate::{lexer::TagType, parser::impl_parse, Accept, Visitor};
44

55
#[derive(Debug, Clone)]
66
pub struct Brief {
@@ -15,3 +15,9 @@ impl_parse!(Brief, {
1515
.delimited_by(just(TagType::BriefStart), just(TagType::BriefEnd))
1616
.map(|desc| Self { desc })
1717
});
18+
19+
impl<T: Visitor> Accept<T> for Brief {
20+
fn accept(&self, n: &T, s: &T::S) -> T::R {
21+
n.brief(self, s)
22+
}
23+
}

src/parser/tags/class.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use chumsky::{select, Parser};
33
use crate::{
44
lexer::{Name, Scope, TagType, Ty},
55
parser::{impl_parse, Prefix, See},
6+
Accept, Visitor,
67
};
78

89
#[derive(Debug, Clone)]
@@ -66,3 +67,9 @@ impl_parse!(Class, {
6667
prefix: Prefix::default(),
6768
})
6869
});
70+
71+
impl<T: Visitor> Accept<T> for Class {
72+
fn accept(&self, n: &T, s: &T::S) -> T::R {
73+
n.class(self, s)
74+
}
75+
}

src/parser/tags/divider.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
use chumsky::select;
22

3-
use crate::{lexer::TagType, parser::impl_parse};
3+
use crate::{lexer::TagType, parser::impl_parse, Accept, Visitor};
44

55
#[derive(Debug, Clone)]
66
pub struct Divider(pub char);
77

88
impl_parse!(Divider, {
99
select! { TagType::Divider(rune) => Self(rune) }
1010
});
11+
12+
impl<T: Visitor> Accept<T> for Divider {
13+
fn accept(&self, n: &T, s: &T::S) -> T::R {
14+
n.divider(self, s)
15+
}
16+
}

src/parser/tags/func.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use chumsky::{select, Parser};
33
use crate::{
44
lexer::{Name, Op, TagType, Ty},
55
parser::{impl_parse, Prefix, See},
6+
Accept, Visitor,
67
};
78

89
use super::Usage;
@@ -96,3 +97,9 @@ impl_parse!(Func, {
9697
},
9798
)
9899
});
100+
101+
impl<T: Visitor> Accept<T> for Func {
102+
fn accept(&self, n: &T, s: &T::S) -> T::R {
103+
n.func(self, s)
104+
}
105+
}

src/parser/tags/module.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use chumsky::select;
22

3-
use crate::{lexer::TagType, parser::impl_parse};
3+
use crate::{lexer::TagType, parser::impl_parse, Accept, Visitor};
44

55
#[derive(Debug, Clone)]
66
pub struct Module {
@@ -11,3 +11,9 @@ pub struct Module {
1111
impl_parse!(Module, {
1212
select! { TagType::Module(name, desc) => Self { name, desc } }
1313
});
14+
15+
impl<T: Visitor> Accept<T> for Module {
16+
fn accept(&self, n: &T, s: &T::S) -> T::R {
17+
n.module(self, s)
18+
}
19+
}

src/parser/tags/see.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use chumsky::{select, Parser};
22

3-
use crate::{lexer::TagType, parser::impl_parse};
3+
use crate::{lexer::TagType, parser::impl_parse, Accept, Visitor};
44

55
#[derive(Debug, Clone)]
66
pub struct See {
@@ -12,3 +12,9 @@ impl_parse!(See, {
1212
.repeated()
1313
.map(|refs| Self { refs })
1414
});
15+
16+
impl<T: Visitor> Accept<T> for See {
17+
fn accept(&self, n: &T, s: &T::S) -> T::R {
18+
n.see(self, s)
19+
}
20+
}

src/parser/tags/tag.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
use chumsky::select;
22

3-
use crate::{lexer::TagType, parser::impl_parse};
3+
use crate::{lexer::TagType, parser::impl_parse, Accept, Visitor};
44

55
#[derive(Debug, Clone)]
66
pub struct Tag(pub String);
77

88
impl_parse!(Tag, {
99
select! { TagType::Tag(x) => Self(x) }
1010
});
11+
12+
impl<T: Visitor> Accept<T> for Tag {
13+
fn accept(&self, n: &T, s: &T::S) -> T::R {
14+
n.tag(self, s)
15+
}
16+
}

0 commit comments

Comments
 (0)