Skip to main content

coven_storage/
settings.rs

1use crate::{StorageConfig, StorageError};
2use coven_foundation::files::StoreDirAccess;
3use coven_foundation::files::{StoreDir, StoreFile};
4
5/// Read the location recorded in the store directory's settings file, with
6/// absence distinct from malformed settings. Credentials never enter this file.
7pub fn recorded_config(directory: &StoreDir) -> Result<Option<StorageConfig>, StorageError> {
8    let Some(bytes) = directory.owned_file(StoreFile::StorageSettings).read_optional()? else {
9        return Ok(None);
10    };
11    Ok(Some(StorageConfig::decode(&bytes)?))
12}
13
14/// Atomically record `config` as the store's location after the facade has
15/// established the connection.
16pub fn record_config(directory: &StoreDir, config: &StorageConfig) -> Result<(), StorageError> {
17    let bytes = config.encode()?;
18    directory.owned_file(StoreFile::StorageSettings).replace(bytes.as_bytes())?;
19    Ok(())
20}
21
22/// Remove the recorded location after the facade successfully removes
23/// credentials.
24pub fn remove_recorded_config(directory: &StoreDir) -> Result<(), StorageError> {
25    Ok(directory.owned_file(StoreFile::StorageSettings).remove()?)
26}
27
28impl StorageConfig {
29    /// Encode the validated location as the settings file holds it, without
30    /// any storage credentials.
31    pub(crate) fn encode(&self) -> Result<coven_crypto::SecretBytes, StorageError> {
32        self.validate()?;
33        crate::secret_json::encode(self)
34    }
35
36    /// Decode the settings file's location; unknown fields and credential
37    /// payloads fail.
38    pub(crate) fn decode(bytes: &[u8]) -> Result<Self, StorageError> {
39        let location: Self = crate::secret_json::decode(bytes)?;
40        location.validate()?;
41        Ok(location)
42    }
43}
44
45#[cfg(test)]
46#[path = "settings_tests.rs"]
47mod tests;