///|
pub fn parse_manifest(text : String) -> ManifestInfo {
let fields : Array[ManifestField] = []
let duplicates : Array[String] = []
let malformed : Array[Int] = []
let lines = split_lines(text)
let mut index = 0
while index < lines.length() {
let line_no = index + 1
let line = trim_ascii(lines[index])
if line.length() > 0 && !starts_with(line, "//") {
match index_of(line, "=") {
None => malformed.push(line_no)
Some(eq) => {
let key = trim_ascii(slice(line, 0, eq))
let value = strip_quotes(slice(line, eq + 1, line.length()))
if key.length() == 0 {
malformed.push(line_no)
} else {
if manifest_has_key(fields, key) && !array_contains(duplicates, key) {
duplicates.push(key)
}
fields.push(field(key, value, line_no))
}
}
}
}
index += 1
}
manifest_info(fields, duplicates, malformed)
}
///|
pub fn ManifestInfo::get(self : ManifestInfo, key : String) -> String? {
let mut index = 0
while index < self.fields.length() {
if self.fields[index].key == key {
return Some(self.fields[index].value)
}
index += 1
}
None
}
///|
pub fn ManifestInfo::has(self : ManifestInfo, key : String) -> Bool {
match self.get(key) {
Some(_) => true
None => false
}
}
///|
pub fn ManifestInfo::package_name(self : ManifestInfo) -> String {
match self.get("name") {
Some(value) => value
None => ""
}
}
///|
pub fn ManifestInfo::version(self : ManifestInfo) -> String {
match self.get("version") {
Some(value) => value
None => ""
}
}
///|
fn manifest_has_key(fields : Array[ManifestField], key : String) -> Bool {
let mut index = 0
while index < fields.length() {
if fields[index].key == key {
return true
}
index += 1
}
false
}
///|
fn array_contains(items : Array[String], value : String) -> Bool {
let mut index = 0
while index < items.length() {
if items[index] == value {
return true
}
index += 1
}
false
}
///|
fn valid_package_name(value : String) -> Bool {
match index_of(value, "/") {
None => false
Some(pos) =>
pos > 0 &&
pos + 1 < value.length() &&
valid_slug(slice(value, 0, pos)) &&
valid_slug(slice(value, pos + 1, value.length()))
}
}
///|
fn valid_slug(value : String) -> Bool {
if value.length() == 0 {
return false
}
let mut index = 0
while index < value.length() {
if !is_ident_char(code_at(value, index)) {
return false
}
index += 1
}
true
}
///|
fn valid_semver(value : String) -> Bool {
parse_semver(value).valid
}