Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions lib/dsc-lib-registry/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ pub enum RegistryValueData {
}

#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename = "Registry", deny_unknown_fields)]
pub struct Registry {
#[serde(rename = "RegistryKey", deny_unknown_fields)]
pub struct RegistryKey {
/// The path to the registry key.
#[serde(rename = "keyPath")]
pub key_path: String,
Expand All @@ -34,6 +34,30 @@ pub struct Registry {
pub exist: Option<bool>,
}

#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename = "RegistryList", deny_unknown_fields)]
pub struct RegistryList {
/// One or more registry keys/values to manage.
#[serde(rename = "registryKeys")]
pub registry_keys: Vec<RegistryKey>,
/// The information from a config set --what-if operation.
#[serde(rename = "_metadata", skip_serializing_if = "Option::is_none")]
pub metadata: Option<Metadata>,
}

#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum Registry {
List(RegistryList),
Single(RegistryKey),
}

impl Default for Registry {
fn default() -> Self {
Registry::Single(RegistryKey::default())
}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct Metadata {
Expand Down
51 changes: 30 additions & 21 deletions lib/dsc-lib-registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use registry::{Data, Hive, RegKey, Security, key, value};
use rust_i18n::t;
use utfx::{U16CString, UCString};
use crate::config::{Metadata, Registry, RegistryValueData};
use crate::config::{Metadata, RegistryKey, RegistryValueData};
use crate::error::RegistryError;

rust_i18n::i18n!("locales", fallback = "en-us");
Expand All @@ -13,27 +13,36 @@ pub mod error;
pub mod config;

pub struct RegistryHelper {
config: Registry,
config: RegistryKey,
hive: Hive,
subkey: String,
what_if: bool,
}

impl RegistryHelper {
/// Create a new `RegistryHelper` from json.
/// Create a new `RegistryHelper` from json describing a single registry key.
///
/// # Arguments
///
/// * `config` - The string with registry configuration information.
/// * `config` - JSON for a single `RegistryKey` instance.
///
/// # Errors
///
/// * `RegistryError` - The error that occurred.
pub fn new_from_json(config: &str) -> Result<Self, RegistryError> {
let registry: Registry = match serde_json::from_str(config) {
let registry: RegistryKey = match serde_json::from_str(config) {
Ok(config) => config,
Err(e) => return Err(RegistryError::Json(e)),
};
Self::new_from_key(registry)
}

/// Create a new `RegistryHelper` from an already-parsed `RegistryKey`.
///
/// # Errors
///
/// * `RegistryError` - The error that occurred.
pub fn new_from_key(registry: RegistryKey) -> Result<Self, RegistryError> {
let key_path = registry.key_path.clone();
let (hive, subkey) = get_hive_from_path(&key_path)?;

Expand All @@ -58,7 +67,7 @@ impl RegistryHelper {
/// * `RegistryError` - The error that occurred.
pub fn new(key_path: &str, value_name: Option<String>, value_data: Option<RegistryValueData>) -> Result<Self, RegistryError> {
let (hive, subkey) = get_hive_from_path(key_path)?;
let config = Registry {
let config = RegistryKey {
key_path: key_path.to_string(),
value_name,
value_data,
Expand All @@ -83,20 +92,20 @@ impl RegistryHelper {
///
/// # Returns
///
/// * `Registry` - The registry struct.
/// * `RegistryKey` - The registry key state.
///
/// # Errors
///
/// * `RegistryError` - The error that occurred.
pub fn get(&self) -> Result<Registry, RegistryError> {
pub fn get(&self) -> Result<RegistryKey, RegistryError> {
let exist: bool;
let (reg_key, _subkey) = match self.open(Security::Read) {
Ok((reg_key, subkey)) => {
(reg_key, subkey)
},
Err(RegistryError::RegistryKeyNotFound(_)) => {
exist = false;
return Ok(Registry {
return Ok(RegistryKey {
key_path: self.config.key_path.clone(),
exist: Some(exist),
..Default::default()
Expand All @@ -110,7 +119,7 @@ impl RegistryHelper {
Ok(value) => value,
Err(value::Error::NotFound(_,_)) => {
exist = false;
return Ok(Registry {
return Ok(RegistryKey {
key_path: self.config.key_path.clone(),
value_name: Some(value_name.clone()),
exist: Some(exist),
Expand All @@ -120,14 +129,14 @@ impl RegistryHelper {
Err(e) => return Err(RegistryError::RegistryValue(e)),
};

Ok(Registry {
Ok(RegistryKey {
key_path: self.config.key_path.clone(),
value_name: Some(value_name.clone()),
value_data: convert_reg_value(&value)?,
..Default::default()
})
} else {
Ok(Registry {
Ok(RegistryKey {
key_path: self.config.key_path.clone(),
..Default::default()
})
Expand All @@ -138,12 +147,12 @@ impl RegistryHelper {
///
/// # Returns
///
/// * `Registry` - The registry struct.
/// * `RegistryKey` - The registry key state when applicable.
///
/// # Errors
///
/// * `RegistryError` - The error that occurred.
pub fn set(&self) -> Result<Option<Registry>, RegistryError> {
pub fn set(&self) -> Result<Option<RegistryKey>, RegistryError> {
let mut what_if_metadata: Vec<String> = Vec::new();
let reg_key = match self.open(Security::Write) {
Ok((reg_key, _subkey)) => Some(reg_key),
Expand Down Expand Up @@ -224,7 +233,7 @@ impl RegistryHelper {
};

if self.what_if {
return Ok(Some(Registry {
return Ok(Some(RegistryKey {
key_path: self.config.key_path.clone(),
value_data: convert_reg_value(&data)?,
value_name: self.config.value_name.clone(),
Expand All @@ -239,7 +248,7 @@ impl RegistryHelper {
}

if self.what_if {
return Ok(Some(Registry {
return Ok(Some(RegistryKey {
key_path: self.config.key_path.clone(),
metadata: if what_if_metadata.is_empty() { None } else { Some(Metadata { what_if: Some(what_if_metadata) })},
..Default::default()
Expand All @@ -258,7 +267,7 @@ impl RegistryHelper {
/// # Errors
///
/// * `RegistryError` - The error that occurred.
pub fn remove(&self) -> Result<Option<Registry>, RegistryError> {
pub fn remove(&self) -> Result<Option<RegistryKey>, RegistryError> {
// For deleting a value, we need SetValue permission (KEY_SET_VALUE).
// Try to open with the minimal required permission.
// If that fails due to permission, try with AllAccess as a fallback.
Expand All @@ -284,7 +293,7 @@ impl RegistryHelper {
if let Some(value_name) = &self.config.value_name {
if self.what_if {
what_if_metadata.push(t!("registry_helper.whatIfDeleteValue", value_name = value_name).to_string());
return Ok(Some(Registry {
return Ok(Some(RegistryKey {
key_path: self.config.key_path.clone(),
value_name: Some(value_name.clone()),
metadata: Some(Metadata { what_if: Some(what_if_metadata) }),
Expand Down Expand Up @@ -312,7 +321,7 @@ impl RegistryHelper {

if self.what_if {
what_if_metadata.push(t!("registry_helper.whatIfDeleteSubkey", subkey_name = subkey_name).to_string());
return Ok(Some(Registry {
return Ok(Some(RegistryKey {
key_path: self.config.key_path.clone(),
metadata: Some(Metadata { what_if: Some(what_if_metadata) }),
..Default::default()
Expand Down Expand Up @@ -378,9 +387,9 @@ impl RegistryHelper {
Ok((parent_key, subkeys))
}

fn handle_error_or_what_if(&self, error: RegistryError) -> Result<Option<Registry>, RegistryError> {
fn handle_error_or_what_if(&self, error: RegistryError) -> Result<Option<RegistryKey>, RegistryError> {
if self.what_if {
return Ok(Some(Registry {
return Ok(Some(RegistryKey {
key_path: self.config.key_path.clone(),
metadata: Some(Metadata { what_if: Some(vec![error.to_string()]) }),
..Default::default()
Expand Down
2 changes: 2 additions & 0 deletions resources/registry/locales/en-us.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ tracingInitError = "Unable to set global default tracing subscriber. Tracing is
debugAttach = "attach debugger to pid %{pid} and press any key to continue"
debugEventReadError = "Error: Failed to read event: %{err}"
debugEventUnexpectedError = "Unexpected event: %{e}"
jsonSerializationError = "Failed to serialize result to JSON: %{err}"
emptyRegistryKeysArray = "The 'registryKeys' array must contain at least one entry."
Loading
Loading