Skip to main content

px_wsdom_ts_parse/parser/
method.rs

1use winnow::{
2    combinator::{alt, delimited, opt, preceded, separated0, separated_pair},
3    PResult, Parser,
4};
5
6use super::{
7    generic::GenericsDeclaration,
8    ts_type::TsType,
9    util::{token, token_word, word0, word1, Parsable},
10};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct Method<'a> {
14    pub name: MethodName<'a>,
15    pub generics: GenericsDeclaration<'a>,
16    pub args: Vec<MethodArg<'a>>,
17    pub ret: Option<TsType<'a>>,
18    pub optional: bool,
19    pub is_static: bool,
20}
21impl<'a> Parsable<'a> for Method<'a> {
22    fn parse(input: &mut &'a str) -> PResult<Self> {
23        (
24            (
25                opt(token_word("static")),
26                MethodName::parse,
27                opt(token("?")),
28                opt(GenericsDeclaration::parse),
29                delimited(
30                    token('('),
31                    separated0(MethodArg::parse, token(',')),
32                    token(')'),
33                ),
34            ),
35            opt(preceded(token(':'), TsType::parse)),
36        )
37            .parse_next(input)
38            .map(|((is_static, name, optional, generics, args), ret)| Self {
39                name,
40                generics: generics.unwrap_or_default(),
41                args,
42                ret,
43                optional: optional.is_some(),
44                is_static: is_static.is_some(),
45            })
46    }
47}
48
49#[derive(Debug, Clone, PartialEq, Eq)]
50pub struct MethodArg<'a> {
51    pub name: &'a str,
52    pub optional: bool,
53    pub ty: TsType<'a>,
54    pub variadic: bool,
55}
56impl<'a> Parsable<'a> for MethodArg<'a> {
57    fn parse(input: &mut &'a str) -> PResult<Self> {
58        separated_pair(
59            (opt(token("...")), word1, opt(token('?'))),
60            token(':'),
61            TsType::parse,
62        )
63        .map(|((variadic, name, optional), ty)| Self {
64            name,
65            optional: optional.is_some(),
66            ty,
67            variadic: variadic.is_some(),
68        })
69        .parse_next(input)
70    }
71}
72
73#[derive(Debug, Clone, PartialEq, Eq, Hash)]
74pub enum MethodName<'a> {
75    Nothing,
76    Constructor,
77    Iterator,
78    Name(&'a str),
79}
80impl<'a> Parsable<'a> for MethodName<'a> {
81    fn parse(input: &mut &'a str) -> PResult<Self> {
82        alt((
83            delimited(token('['), "Symbol.iterator", token(']')).map(|_| Self::Iterator),
84            word0.map(|s| match s {
85                "" => Self::Nothing,
86                "new" | "constructor" => Self::Constructor,
87                s => Self::Name(s),
88            }),
89        ))
90        .parse_next(input)
91    }
92}