1use std::sync::Arc;
2
3use nom::{
4 branch::alt,
5 bytes::complete::tag,
6 combinator::{map, opt},
7 sequence::tuple,
8 IResult,
9};
10
11use super::{blank, list_separator, path::Path, Parser};
12
13#[derive(Debug, Clone)]
14pub enum Type {
15 String,
16 Void,
17 Byte,
18 Bool,
19 Binary,
20 I8,
21 I16,
22 I32,
23 I64,
24 Double,
25 List { value: Arc<Type> },
26 Set { value: Arc<Type> },
27 Map { key: Arc<Type>, value: Arc<Type> },
28 Path(Path),
29}
30
31impl<'a> Parser<'a> for Type {
32 fn parse(input: &'a str) -> IResult<&'a str, Self> {
33 alt((
34 map(tag("string"), |_| Type::String),
35 map(tag("void"), |_| Type::Void),
36 map(tag("byte"), |_| Type::Byte),
37 map(tag("bool"), |_| Type::Bool),
38 map(tag("binary"), |_| Type::Binary),
39 map(tag("i8"), |_| Type::I8),
40 map(tag("i16"), |_| Type::I16),
41 map(tag("i32"), |_| Type::I32),
42 map(tag("i64"), |_| Type::I64),
43 map(tag("double"), |_| Type::Double),
44 map(
45 tuple((
46 tag("list"),
47 opt(blank),
48 tag("<"),
49 opt(blank),
50 Type::parse,
51 opt(blank),
52 tag(">"),
53 )),
54 |(_, _, _, _, inner_type, _, _)| Type::List {
55 value: Arc::new(inner_type),
56 },
57 ),
58 map(
59 tuple((
60 tag("set"),
61 opt(blank),
62 tag("<"),
63 opt(blank),
64 Type::parse,
65 opt(blank),
66 tag(">"),
67 )),
68 |(_, _, _, _, inner_type, _, _)| Type::Set {
69 value: Arc::new(inner_type),
70 },
71 ),
72 map(
73 tuple((
74 tag("map"),
75 opt(blank),
76 tag("<"),
77 opt(blank),
78 Type::parse,
79 opt(blank),
80 list_separator,
81 opt(blank),
82 Type::parse,
83 opt(blank),
84 tag(">"),
85 )),
86 |(_, _, _, _, key_type, _, _, _, value_type, _, _)| Type::Map {
87 key: Arc::new(key_type),
88 value: Arc::new(value_type),
89 },
90 ),
91 map(Path::parse, Type::Path),
92 ))(input)
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn test_type() {
102 let input = "string";
103 match super::Type::parse(input) {
104 Ok((remain, ty)) => {
105 assert_eq!(remain, "");
106 match ty {
107 Type::String => {}
108 _ => panic!("Expected String"),
109 }
110 }
111 Err(e) => panic!("Error: {e:?}"),
112 }
113 }
114}