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
use std::io::{Read,Seek};
use crate::nom::{
IResult,
all_consuming,
line_ending,
many0,
many1,
tag,
opt,
};
use crate::{
Decode,
Error,
ErrorKind,
ScriptField,
Gtg,
ScriptReference,
Tng,
ScriptExpression,
};
impl Decode for Gtg {
fn decode<Source>(source: &mut Source) -> Result<Gtg, Error> where
Source: Read + Seek
{
let mut input = Vec::new();
source.read_to_end(&mut input)?;
let (_, gtg) = all_consuming(Gtg::decode_gtg)(&input)?;
Ok(gtg)
}
}
impl Gtg {
pub fn decode_gtg(input: &[u8]) -> IResult<&[u8], Gtg, Error> {
let (input, maps) = many1(Self::decode_gtg_map)(input)?;
Ok((input, Gtg { maps: maps }))
}
pub fn decode_gtg_map(input: &[u8]) -> IResult<&[u8], Tng, Error> {
let (input, _start) = Self::decode_gtg_field_named("NEWMAP")(input)?;
let (input, tng) = Tng::decode_tng(input)?;
let (input, _end) = Self::decode_gtg_field_named("ENDMAP")(input)?;
Ok((input, tng))
}
pub fn decode_gtg_field_named(name: &'static str) -> impl Fn(&[u8]) -> IResult<&[u8], ScriptField, Error> {
move |input: &[u8]| {
let (input, _line_ending) = many0(line_ending)(input)?;
let (input, reference) = ScriptReference::decode_reference(input)?;
let (input, _space) = opt(tag(" "))(input)?;
let (input, expression) = ScriptExpression::decode_expression(input)?;
let (input, _line_ending) = many1(line_ending)(input)?;
let field_name = match reference {
ScriptReference::Name(x) => x,
ScriptReference::ScriptAccessor(_) => return Err(nom::Err::Error(Error::Fable(ErrorKind::InvalidInstruction))),
};
if field_name != name {
return Err(nom::Err::Error(Error::Fable(ErrorKind::InvalidTagName)));
}
Ok(
(
input,
ScriptField {
reference: ScriptReference::Name(field_name),
value: Box::new(expression),
}
)
)
}
}
}