px_wsdom_ts_parse/parser/
field.rs1use winnow::{
2 combinator::{alt, delimited, opt, separated_pair},
3 PResult, Parser,
4};
5
6use super::{
7 ts_type::TsType,
8 util::{quote_backslash_escape, token, token_word, word1, Parsable},
9};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct Field<'a> {
13 pub name: FieldName<'a>,
14 pub readonly: bool,
15 pub optional: bool,
16 pub ty: TsType<'a>,
17}
18impl<'a> Parsable<'a> for Field<'a> {
19 fn parse(input: &mut &'a str) -> PResult<Self> {
20 separated_pair(
21 (
22 opt(token_word("readonly")),
23 FieldName::parse,
24 opt(token('?')),
25 ),
26 token(':'),
27 TsType::parse,
28 )
29 .parse_next(input)
30 .map(|((readonly, name, optional), ty)| Self {
31 readonly: readonly.is_some(),
32 name,
33 optional: optional.is_some(),
34 ty,
35 })
36 }
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub enum FieldName<'a> {
41 Name(&'a str),
42 Wildcard { name: &'a str, ty: TsType<'a> },
43}
44impl<'a> Parsable<'a> for FieldName<'a> {
45 fn parse(input: &mut &'a str) -> PResult<Self> {
46 alt((
47 word1.map(Self::Name),
48 quote_backslash_escape('"').map(Self::Name),
49 delimited(
50 token('['),
51 separated_pair(word1, token(':'), TsType::parse),
52 token(']'),
53 )
54 .map(|(name, ty)| Self::Wildcard { name, ty }),
55 ))
56 .parse_next(input)
57 }
58}