px_wsdom_ts_parse/parser/
method.rs1use 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}