wolfrpg_map_parser/command/
number_condition_command.rs

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
#[cfg(feature = "serde")]
use serde::Serialize;
use crate::command::common::case::Case;
use crate::command::common::CASES_END_SIGNATURE;
use crate::command::number_condition_command::condition::Condition;

pub mod condition;
pub mod operator;

#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct NumberConditionCommand {
    else_case: bool,
    conditions: Vec<Condition>,
    cases: Vec<Case>,
}

impl NumberConditionCommand {
    pub fn parse(bytes: &[u8]) -> (usize, u32, Self) {
        let mut offset: usize = 0;

        let (case_count, else_case): (u8, bool) = Self::parse_case_count(bytes[offset]);
        offset += 1;

        offset += 3; // padding

        let (bytes_read, conditions): (usize, Vec<Condition>)
            = Self::parse_conditions(&bytes[offset..], case_count as usize);

        offset += bytes_read;

        offset += 3; // Command end

        let case_count: usize = case_count as usize + else_case as usize;
        let (bytes_read, mut commands_read, cases): (usize, u32, Vec<Case>)
            = Case::parse_multiple(&bytes[offset..], case_count);

        offset += bytes_read;

        let cases_end: &[u8] = &bytes[offset..offset+8];
        offset += 8;
        commands_read += 1;

        if cases_end != CASES_END_SIGNATURE {
            panic!("Invalid cases end.");
        }

        (offset, commands_read, Self {
            else_case,
            conditions,
            cases
        })
    }

    fn parse_case_count(cases: u8) -> (u8, bool) {
        (cases & 0x0f, cases & 0b00010000 != 0)
    }

    fn parse_conditions(bytes: &[u8], condition_count: usize) -> (usize, Vec<Condition>) {
        let mut offset: usize = 0;
        let mut conditions: Vec<Condition> = Vec::with_capacity(condition_count);

        for _ in 0..condition_count {
            let (bytes_read, condition): (usize, Condition)
                = Condition::parse(&bytes[offset..]);
            conditions.push(condition);
            offset += bytes_read;
        }

        (offset, conditions)
    }

    pub fn else_case(&self) -> bool {
        self.else_case
    }

    pub fn else_case_mut(&mut self) -> &mut bool {
        &mut self.else_case
    }

    pub fn conditions(&self) -> &Vec<Condition> {
        &self.conditions
    }

    pub fn conditions_mut(&mut self) -> &mut Vec<Condition> {
        &mut self.conditions
    }

    pub fn cases(&self) -> &Vec<Case> {
        &self.cases
    }

    pub fn cases_mut(&mut self) -> &mut Vec<Case> {
        &mut self.cases
    }
}