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
use {
    Constant,
    Call,
    Instruction,
    Options,
    OptionsTemplate,
};

/// All the data required to load the processor.
#[derive(Debug)]
pub struct Template<V> {
    pub constants: Options<Constant, V>,
    pub calls_template: OptionsTemplate<Call>,
    pub instructions: Vec<Instruction>,
    pub bindings_capacity: u32,
}

impl<V> Template<V> {
    pub fn new(
        constants: Options<Constant, V>,
        calls_template: OptionsTemplate<Call>,
        instructions: Vec<Instruction>,
        bindings_capacity: u32,
    ) -> Template<V> {
        Template {
            constants: constants,
            calls_template: calls_template,
            instructions: instructions,
            bindings_capacity: bindings_capacity,
        }
    }

    pub fn empty() -> Template<V> {
        Template {
            constants: Options::empty(),
            calls_template: OptionsTemplate::empty(),
            instructions: vec![],
            bindings_capacity: 0,
        }
    }

    pub fn with_constant(mut self, index: Constant, value: V) -> Self {
        self.constants.push(index, value);
        self
    }

    pub fn push_constant(&mut self, index: Constant, value: V) -> &mut Self {
        self.constants.push(index, value);
        self
    }

    pub fn with_call<S: Into<String>>(mut self, key: S, index: Call) -> Self {
        self.calls_template.push(key, index);
        self
    }

    pub fn push_instruction(&mut self, instruction: Instruction) {
        self.instructions.push(instruction);
    }

    pub fn with_instructions<I: IntoIterator<Item=Instruction>>(mut self, instructions: I) -> Self {
        self.instructions.extend(instructions.into_iter());
        self
    }
}