///|
/// Failures while reading application metadata managed by Proton tooling.
pub(all) suberror AppMetadataError {
MissingPackageMetadata
MissingField(field~ : String)
InvalidMetadata(detail~ : String)
} derive(Debug, Eq)
///|
pub extend AppMetadataError with Eq::{not_equal, equal}
///|
pub extend AppMetadataError with Debug::{to_repr}
///|
pub fn AppMetadataError::message(self : AppMetadataError) -> String {
match self {
MissingPackageMetadata => "application package metadata is not configured"
MissingField(field~) => "application package metadata requires " + field
InvalidMetadata(detail~) =>
"invalid application package metadata: " + detail
}
}
///|
impl Show for AppMetadataError with fn output(self, logger) {
logger.write_string(self.message())
}
///|
pub extend AppMetadataError with Show::{to_string, output}
///|
priv struct ApplicationMetadata {
name : String
version : String
}
///|
/// Returns the product name from managed development or packaged metadata.
pub fn App::name(self : App) -> String raise AppMetadataError {
self.application_metadata().name
}
///|
/// Returns the application version from managed development or packaged
/// metadata.
pub fn App::version(self : App) -> String raise AppMetadataError {
self.application_metadata().version
}
///|
fn App::application_metadata(
self : App,
) -> ApplicationMetadata raise AppMetadataError {
match packaged_application_manifest_path() {
Some(path) => load_packaged_application_metadata(path)
None =>
match self.application_identity {
Some(ProjectConfig(_)) =>
load_project_application_metadata(project_config_path())
Some(Explicit(_)) | None => raise MissingPackageMetadata
}
}
}
///|
fn load_project_application_metadata(
path : String,
) -> ApplicationMetadata raise AppMetadataError {
let config = @proton_config.load_project_config_from_file(path) catch {
error => raise InvalidMetadata(detail=error.message())
}
project_application_metadata(config)
}
///|
fn project_application_metadata(
config : @proton_config.ProjectConfig,
) -> ApplicationMetadata raise AppMetadataError {
guard config.package_config() is Some(package_config) else {
raise MissingPackageMetadata
}
ApplicationMetadata::{
name: normalize_application_metadata_string(
package_config.product_name,
"product_name",
),
version: normalize_application_metadata_string(
package_config.version(),
"version",
),
}
}
///|
fn load_packaged_application_metadata(
path : String,
) -> ApplicationMetadata raise AppMetadataError {
let source = @mbfs.read_file_to_string(path, encoding="utf8") catch {
error =>
raise InvalidMetadata(
detail="failed to read " + path + ": " + @debug.render(Repr(error)),
)
}
packaged_application_metadata_from_json(source)
}
///|
fn packaged_application_metadata_from_json(
source : String,
) -> ApplicationMetadata raise AppMetadataError {
let json = @json.parse(source) catch {
error => raise InvalidMetadata(detail=error.to_string())
}
guard json is Object(fields) else {
raise InvalidMetadata(detail="expected an object")
}
let name = required_application_metadata_string(fields, "product_name")
let version = required_application_metadata_string(fields, "version")
ApplicationMetadata::{ name, version, }
}
///|
fn required_application_metadata_string(
fields : Map[String, Json],
field : String,
) -> String raise AppMetadataError {
guard fields.get(field) is Some(String(value)) else {
raise MissingField(field~)
}
normalize_application_metadata_string(value, field)
}
///|
fn normalize_application_metadata_string(
value : String,
field : String,
) -> String raise AppMetadataError {
let value = value.trim().to_owned()
guard value != "" else { raise MissingField(field~) }
value
}