1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::char as cchar;
use nom::combinator::{map, opt};
use nom::sequence::{delimited, terminated, tuple};
use nom::IResult;
use crate::basic::{Identifier, ListSeparator, Separator};
use crate::constant::{ConstValue, IntConstant};
use crate::types::FieldType;
use crate::Parser;
#[derive(Debug, Clone, PartialEq)]
pub struct Field<'a> {
pub id: Option<IntConstant>,
pub required: Option<bool>,
pub type_: FieldType<'a>,
pub name: Identifier<'a>,
pub default: Option<ConstValue<'a>>,
}
impl<'a> Parser<'a> for Field<'a> {
fn parse(input: &'a str) -> IResult<&'a str, Self> {
map(
tuple((
opt(terminated(
IntConstant::parse,
delimited(opt(Separator::parse), cchar(':'), opt(Separator::parse)),
)),
opt(terminated(
alt((
map(tag("required"), |_| true),
map(tag("optional"), |_| false),
)),
Separator::parse,
)),
terminated(FieldType::parse, Separator::parse),
terminated(Identifier::parse, opt(Separator::parse)),
opt(map(
tuple((cchar('='), opt(Separator::parse), ConstValue::parse)),
|(_, _, cv)| cv,
)),
opt(Separator::parse),
opt(ListSeparator::parse),
)),
|(id, required, type_, name, default, _, _)| Self {
id,
required,
type_,
name,
default,
},
)(input)
}
}
#[cfg(test)]
mod test {
use crate::basic::Literal;
use super::*;
#[test]
fn test_field() {
let expected = Field {
id: None,
required: Some(true),
type_: FieldType::String,
name: Identifier::from("name"),
default: Some(ConstValue::Literal(Literal::from("ihciah"))),
};
assert_eq!(
Field::parse("required string name = 'ihciah'")
.unwrap()
.1,
expected
);
assert_eq!(
Field::parse("required string name='ihciah';").unwrap().1,
expected
);
let expected = Field {
id: Some(IntConstant::from(3)),
required: Some(true),
type_: FieldType::String,
name: Identifier::from("name"),
default: Some(ConstValue::Literal(Literal::from("ihciah"))),
};
assert_eq!(
Field::parse("3 : required string name = 'ihciah'")
.unwrap()
.1,
expected
);
assert_eq!(
Field::parse("3:required string name='ihciah';").unwrap().1,
expected
);
}
}