///|
pub(all) struct Rule {
name : String
command : String
} derive(Debug, Eq)
///|
pub(all) struct BuildEdge {
rule : String
inputs : Array[String]
outputs : Array[String]
} derive(Debug, Eq)
///|
pub(all) struct Manifest {
rules : Map[String, Rule]
builds : Array[BuildEdge]
} derive(Debug, Eq)
///|
pub fn BuildEdge::key(self : BuildEdge) -> String {
let mut key = self.rule + "::"
for i, output in self.outputs {
if i > 0 {
key += ","
}
key += output
}
key
}
///|
pub fn BuildEdge::render_command(
self : BuildEdge,
rules : Map[String, Rule],
) -> Result[String, String] {
match rules.get(self.rule) {
Some(rule) => {
let raw_cmd = rule.command
let in_str = join_strings(self.inputs, " ")
let out_str = join_strings(self.outputs, " ")
Ok(
replace_string(replace_string(raw_cmd, "$in", in_str), "$out", out_str),
)
}
None => Err("Unknown rule: " + self.rule)
}
}
///|
fn join_strings(arr : Array[String], separator : String) -> String {
let mut result = ""
for i, value in arr {
if i > 0 {
result += separator
}
result += value
}
result
}
///|
fn replace_string(s : String, pattern : String, replacement : String) -> String {
let mut result = ""
let mut i = 0
let pattern_len = pattern.length()
while i < s.length() {
if i + pattern_len <= s.length() &&
s[i:i + pattern_len].to_owned() == pattern {
result += replacement
i += pattern_len
} else {
let ch = get_char_at(s, i)
result += "\{ch}"
i += 1
}
}
result
}