v0.1.3-pre.007
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-config-lib/src/registry.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
/// Bootstrap argument used to replace a known Config filename mapping.
|
||||
pub const ARG_FILE_MAP: &str = "--filemap";
|
||||
@@ -43,12 +43,13 @@ pub enum ConfigFileKind {
|
||||
Schema,
|
||||
}
|
||||
|
||||
/// Logical descriptor associating a stable file identifier with its physical filename and root category.
|
||||
/// Logical descriptor associating a stable file identifier with its physical filename, root category and optional validation schema.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct ConfigFileDescriptor {
|
||||
file_id: ConfigFileId,
|
||||
kind: ConfigFileKind,
|
||||
filename: std::path::PathBuf,
|
||||
schema_file_id: std::option::Option<ConfigFileId>,
|
||||
}
|
||||
|
||||
impl ConfigFileDescriptor {
|
||||
@@ -70,7 +71,18 @@ impl ConfigFileDescriptor {
|
||||
return self.filename.as_path();
|
||||
}
|
||||
|
||||
fn new(file_id: &'static str, kind: ConfigFileKind, filename: &'static str) -> ksp_core_lib::Result<Self> {
|
||||
/// Returns the logical schema identifier associated with this Config document when one is declared.
|
||||
#[must_use]
|
||||
pub fn schema_file_id(&self) -> std::option::Option<&ConfigFileId> {
|
||||
return self.schema_file_id.as_ref();
|
||||
}
|
||||
|
||||
fn new(
|
||||
file_id: &'static str,
|
||||
kind: ConfigFileKind,
|
||||
filename: &'static str,
|
||||
schema_file_id: std::option::Option<&'static str>,
|
||||
) -> ksp_core_lib::Result<Self> {
|
||||
let file_id = ConfigFileId::new(file_id);
|
||||
let file_id = match file_id {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -82,8 +94,13 @@ impl ConfigFileDescriptor {
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
}
|
||||
let filename = validate_relative_filename(&file_id, std::path::PathBuf::from(filename));
|
||||
return match filename {
|
||||
std::result::Result::Ok(value) => std::result::Result::Ok(Self { file_id, kind, filename: value }),
|
||||
let filename = match filename {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let schema_file_id = parse_schema_file_id(&file_id, kind, schema_file_id);
|
||||
return match schema_file_id {
|
||||
std::result::Result::Ok(value) => std::result::Result::Ok(Self { file_id, kind, filename, schema_file_id: value }),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error),
|
||||
};
|
||||
}
|
||||
@@ -98,12 +115,18 @@ pub struct ConfigFileRegistry {
|
||||
impl ConfigFileRegistry {
|
||||
/// Creates the registry containing the KSP default file mappings known in the current release.
|
||||
pub fn defaults() -> ksp_core_lib::Result<Self> {
|
||||
let logging = ConfigFileDescriptor::new(FILE_ID_STD_LOGGING, ConfigFileKind::Config, DEFAULT_STD_LOGGING_FILENAME);
|
||||
let logging = ConfigFileDescriptor::new(
|
||||
FILE_ID_STD_LOGGING,
|
||||
ConfigFileKind::Config,
|
||||
DEFAULT_STD_LOGGING_FILENAME,
|
||||
std::option::Option::Some(FILE_ID_SCHEMA_STD_LOGGING),
|
||||
);
|
||||
let logging = match logging {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let logging_schema = ConfigFileDescriptor::new(FILE_ID_SCHEMA_STD_LOGGING, ConfigFileKind::Schema, DEFAULT_STD_LOGGING_SCHEMA_FILENAME);
|
||||
let logging_schema =
|
||||
ConfigFileDescriptor::new(FILE_ID_SCHEMA_STD_LOGGING, ConfigFileKind::Schema, DEFAULT_STD_LOGGING_SCHEMA_FILENAME, std::option::Option::None);
|
||||
let logging_schema = match logging_schema {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
@@ -154,7 +177,7 @@ impl ConfigFileRegistry {
|
||||
return std::result::Result::Ok(root.join(descriptor.filename()));
|
||||
}
|
||||
|
||||
/// Replaces the physical filename of one known logical identifier while preserving its kind and logical identity.
|
||||
/// Replaces the physical filename of one known logical identifier while preserving its kind, schema association and logical identity.
|
||||
pub fn with_filename_override(mut self, file_id: &ConfigFileId, filename: impl std::convert::Into<std::path::PathBuf>) -> ksp_core_lib::Result<Self> {
|
||||
let update = self.set_filename_override(file_id, filename.into());
|
||||
return match update {
|
||||
@@ -174,7 +197,12 @@ impl ConfigFileRegistry {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let updated = ConfigFileDescriptor { file_id: descriptor.file_id.clone(), kind: descriptor.kind, filename };
|
||||
let updated = ConfigFileDescriptor {
|
||||
file_id: descriptor.file_id.clone(),
|
||||
kind: descriptor.kind,
|
||||
filename,
|
||||
schema_file_id: descriptor.schema_file_id.clone(),
|
||||
};
|
||||
self.descriptors.insert(file_id.clone(), updated);
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
@@ -190,7 +218,68 @@ fn build_registry<const N: usize>(descriptors: [ConfigFileDescriptor; N]) -> ksp
|
||||
return std::result::Result::Err(duplicate_file_id_error(duplicate_id.as_str()));
|
||||
}
|
||||
}
|
||||
return std::result::Result::Ok(registry);
|
||||
let associations = validate_schema_associations(®istry);
|
||||
return match associations {
|
||||
std::result::Result::Ok(()) => std::result::Result::Ok(registry),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error),
|
||||
};
|
||||
}
|
||||
|
||||
fn parse_schema_file_id(
|
||||
file_id: &ConfigFileId,
|
||||
kind: ConfigFileKind,
|
||||
schema_file_id: std::option::Option<&'static str>,
|
||||
) -> ksp_core_lib::Result<std::option::Option<ConfigFileId>> {
|
||||
return match (kind, schema_file_id) {
|
||||
(ConfigFileKind::Schema, std::option::Option::Some(_)) => {
|
||||
std::result::Result::Err(invalid_file_mapping_with_id_error(file_id.as_str(), "schema descriptors cannot declare another validation schema"))
|
||||
},
|
||||
(ConfigFileKind::Schema, std::option::Option::None) | (ConfigFileKind::Config, std::option::Option::None) => {
|
||||
std::result::Result::Ok(std::option::Option::None)
|
||||
},
|
||||
(ConfigFileKind::Config, std::option::Option::Some(value)) => {
|
||||
let schema_id = ConfigFileId::new(value);
|
||||
match schema_id {
|
||||
std::result::Result::Ok(schema_id) => {
|
||||
if schema_id.as_str().starts_with("schema.") {
|
||||
std::result::Result::Ok(std::option::Option::Some(schema_id))
|
||||
} else {
|
||||
std::result::Result::Err(invalid_file_mapping_with_id_error(
|
||||
file_id.as_str(),
|
||||
"validation schema file_id must use the schema namespace",
|
||||
))
|
||||
}
|
||||
},
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error),
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn validate_schema_associations(registry: &ConfigFileRegistry) -> ksp_core_lib::Result<()> {
|
||||
for descriptor in registry.descriptors.values() {
|
||||
let schema_file_id = match descriptor.schema_file_id() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => continue,
|
||||
};
|
||||
let schema = registry.descriptors.get(schema_file_id);
|
||||
let schema = match schema {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => {
|
||||
return std::result::Result::Err(invalid_file_mapping_with_id_error(
|
||||
descriptor.file_id().as_str(),
|
||||
"validation schema file_id is not registered",
|
||||
));
|
||||
},
|
||||
};
|
||||
if schema.kind() != ConfigFileKind::Schema {
|
||||
return std::result::Result::Err(invalid_file_mapping_with_id_error(
|
||||
descriptor.file_id().as_str(),
|
||||
"validation schema descriptor must have schema kind",
|
||||
));
|
||||
}
|
||||
}
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
|
||||
fn apply_file_map_argument(registry: &mut ConfigFileRegistry, argument: &std::ffi::OsStr) -> ksp_core_lib::Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user