///|
/// A source location. Columns count Unicode scalar values, starting at one.
pub(all) struct Location {
source : String
line : Int
column : Int
} derive(Eq, @debug.Debug)
///|
/// Diagnostics are errors in the supported subset, not pkgconf exit codes.
pub(all) struct Diagnostic {
code : String
message : String
location : Location
} derive(Eq, @debug.Debug)
///|
pub(all) enum EntryKind {
Variable
Field
} derive(Eq, @debug.Debug)
///|
/// Original value is retained for explaining substitutions.
pub(all) struct Entry {
kind : EntryKind
name : String
raw : String
value : String
location : Location
value_location : Location
} derive(Eq, @debug.Debug)
///|
/// A parsed document. Invalid entries are not available to subsequent queries.
pub(all) struct Document {
entries : Array[Entry]
diagnostics : Array[Diagnostic]
} derive(Eq, @debug.Debug)
///|
pub(all) enum VersionOp {
Any
Equal
NotEqual
Less
LessEqual
Greater
GreaterEqual
} derive(Eq, @debug.Debug)
///|
/// Version comparison and transitive dependency resolution are later milestones.
pub(all) struct Requirement {
name : String
op : VersionOp
version : String
} derive(Eq, @debug.Debug)
///|
pub fn Document::field(self : Document, name : String) -> Entry? {
for e in self.entries {
if e.kind == Field && e.name == name {
return Some(e)
}
}
None
}
///|
pub fn Document::variable(self : Document, name : String) -> Entry? {
for e in self.entries {
if e.kind == Variable && e.name == name {
return Some(e)
}
}
None
}
///|
fn diag(code : String, message : String, location : Location) -> Diagnostic {
{ code, message, location, }
}
///|
fn chars_text(chars : Array[Char], start : Int, end : Int) -> String {
let out = StringBuilder()
for i = start; i < end; i = i + 1 {
out.write_char(chars[i])
}
out.to_string()
}
///|
fn whitespace(c : Char) -> Bool {
c == ' ' || c == '\t' || c == '\r' || c == '\n'
}