///|
/// An ordered GIR search path. Each requested namespace is resolved
/// independently, so a primary GIR and its dependencies may live in different
/// directories.
priv struct GirSearchPath {
directories : Array[@path.Path]
}
///|
fn GirSearchPath::GirSearchPath(
directories : ArrayView[String],
) -> GirSearchPath {
let resolved : Array[@path.Path] = []
for directory in directories {
if directory != "" {
let path = @path.Path(directory).resolve()
if !resolved.contains(path) {
resolved.push(path)
}
}
}
{ directories: resolved }
}
///|
/// Resolve one namespace using PATH-style first-match semantics.
async fn GirSearchPath::resolve_gir(
self : GirSearchPath,
gir_name : String,
) -> @path.Path raise SubclassCommandError {
for directory in self.directories {
let candidate = directory.join(@path.Path("\{gir_name}.gir"))
let exists = @fs.exists(candidate.0) catch {
error =>
raise SubclassCommandError::Failure(
"failed to inspect \{candidate.0}: \{error}",
)
}
if exists {
return candidate
}
}
let searched : Array[String] = []
for directory in self.directories {
searched.push(directory.0)
}
raise SubclassCommandError::Failure(
"cannot find \{gir_name}.gir in GIR search path [\{searched.join(", ")}]; repeat --gir-dir or set GI_GIR_PATH",
)
}
///|
/// Validate every configured namespace independently before generation starts.
async fn GirSearchPath::validate(
self : GirSearchPath,
config : @config.GirConfig,
) -> Unit raise SubclassCommandError {
ignore(self.resolve_gir(config.gir))
for gir_name, _ in config.deps {
ignore(self.resolve_gir(gir_name))
}
}