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
use alloc::vec::Vec;
use super::invoke::{Identity, Invoke};
use crate::elements;

/// Data segment builder
pub struct DataSegmentBuilder<F=Identity> {
	callback: F,
	// todo: add mapper once multiple memory refs possible
	mem_index: u32,
	offset: elements::InitExpr,
	value: Vec<u8>,
}

impl DataSegmentBuilder {
	/// New data segment builder
	pub fn new() -> Self {
		DataSegmentBuilder::with_callback(Identity)
	}
}

impl<F> DataSegmentBuilder<F> {
	/// New data segment builder inside the chain context
	pub fn with_callback(callback: F) -> Self {
		DataSegmentBuilder {
			callback: callback,
			mem_index: 0,
			offset: elements::InitExpr::empty(),
			value: Vec::new(),
		}
	}

	/// Set offset initialization instruction. `End` instruction will be added automatically.
	pub fn offset(mut self, instruction: elements::Instruction) -> Self {
		self.offset = elements::InitExpr::new(vec![instruction, elements::Instruction::End]);
		self
	}

	/// Set the bytes value of the segment
	pub fn value(mut self, value: Vec<u8>) -> Self {
		self.value = value;
		self
	}
}

impl<F> DataSegmentBuilder<F> where F: Invoke<elements::DataSegment> {
	/// Finish current builder, spawning resulting struct
	pub fn build(self) -> F::Result {
		self.callback.invoke(
			elements::DataSegment::new(
				self.mem_index,
				Some(self.offset),
				self.value,
			)
		)
	}
}