lemmy_help/parser/tags/
func.rs

1use chumsky::{select, Parser};
2
3use crate::{
4    lexer::{Name, Op, TagType, Ty},
5    parser::{impl_parse, Prefix, See},
6    Accept, Visitor,
7};
8
9use super::Usage;
10
11#[derive(Debug, Clone)]
12pub struct Param {
13    pub name: Name,
14    pub ty: Ty,
15    pub desc: Vec<String>,
16}
17
18impl_parse!(Param, {
19    select! {
20        TagType::Param(name, ty, desc) => (name, ty, desc)
21    }
22    .then(select! { TagType::Comment(x) => x }.repeated())
23    .map(|((name, ty, desc), extra)| {
24        let desc = match desc {
25            Some(d) => {
26                let mut new_desc = Vec::with_capacity(extra.len() + 1);
27                new_desc.push(d);
28                new_desc.extend(extra);
29                new_desc
30            }
31            None => extra,
32        };
33        Self { name, ty, desc }
34    })
35});
36
37#[derive(Debug, Clone)]
38pub struct Return {
39    pub ty: Ty,
40    pub name: Option<String>,
41    pub desc: Vec<String>,
42}
43
44impl_parse!(Return, {
45    select! {
46        TagType::Return(ty, name, desc) => (ty, name, desc)
47    }
48    .then(select! { TagType::Comment(x) => x }.repeated())
49    .map(|((ty, name, desc), extra)| {
50        let desc = match desc {
51            Some(d) => {
52                let mut new_desc = Vec::with_capacity(extra.len() + 1);
53                new_desc.push(d);
54                new_desc.extend(extra);
55                new_desc
56            }
57            None => extra,
58        };
59
60        Self { name, ty, desc }
61    })
62});
63
64#[derive(Debug, Clone)]
65pub struct Func {
66    pub op: Op,
67    pub prefix: Prefix,
68    pub desc: Vec<String>,
69    pub params: Vec<Param>,
70    pub returns: Vec<Return>,
71    pub see: See,
72    pub usage: Option<Usage>,
73}
74
75impl_parse!(Func, {
76    select! {
77        TagType::Comment(x) => x,
78    }
79    .repeated()
80    .then(Param::parse().repeated())
81    .then(Return::parse().repeated())
82    .then(See::parse())
83    .then(Usage::parse().or_not())
84    .then(select! { TagType::Func(prefix, op) => (prefix, op) })
85    .map(
86        |(((((desc, params), returns), see), usage), (prefix, op))| Self {
87            op,
88            prefix: Prefix {
89                left: Some(prefix.clone()),
90                right: Some(prefix),
91            },
92            desc,
93            params,
94            returns,
95            see,
96            usage,
97        },
98    )
99});
100
101impl<T: Visitor> Accept<T> for Func {
102    fn accept(&self, n: &T, s: &T::S) -> T::R {
103        n.func(self, s)
104    }
105}