commit a83d1e2378dab33903741b2562d86badbf68506d
parent 1871733edd8c81a1a2f907cafb1fae1ef270fdfc
Author: triesap <tyson@radroots.org>
Date: Tue, 11 Aug 2026 09:40:34 +0000
runtime-paths: adopt service instance authority
- remove generic namespaces, ambient selectors, raw roots, and bootstrap helpers
- make RuntimeContext the sole public service-instance path constructor
- retain exact Linux, macOS, Windows, and repository-local path behavior
- verify the reviewed API boundary and complete workspace consumer gates
Diffstat:
12 files changed, 1556 insertions(+), 2021 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
@@ -167,6 +167,12 @@ Before editing code:
names are validated single path components, and ordinary manager errors and
`Debug` output must not expose filesystem paths, file contents, or raw
dependency-owned causes.
+- Runtime-path consumers must use the sole typed
+ `services/<service>/<instance>` model through `RuntimeContext`. The generic
+ app/service/worker/shared namespace, public raw root containers, path
+ overrides, ambient process-environment selectors, bootstrap helpers, and
+ duplicate service-instance path constructors are removed breaking surfaces;
+ do not restore them or add compatibility aliases.
- Runtime-distribution and runtime-management service metadata is the sealed
exact Myc/RHI v1 inventory. Both services support multiple validated
instances, one TOML config, explicit initialization with existing-only run,
diff --git a/contracts/api_baselines/radroots_runtime_paths.txt b/contracts/api_baselines/radroots_runtime_paths.txt
@@ -0,0 +1,996 @@
+pub mod radroots_runtime_paths
+pub mod radroots_runtime_paths::context
+pub enum radroots_runtime_paths::context::RuntimeContextError
+pub radroots_runtime_paths::context::RuntimeContextError::InvalidBootstrapBinding
+pub radroots_runtime_paths::context::RuntimeContextError::PathSelection
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContextError
+pub fn radroots_runtime_paths::context::RuntimeContextError::clone(&self) -> radroots_runtime_paths::context::RuntimeContextError
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContextError
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContextError
+pub fn radroots_runtime_paths::context::RuntimeContextError::eq(&self, &radroots_runtime_paths::context::RuntimeContextError) -> bool
+impl core::error::Error for radroots_runtime_paths::context::RuntimeContextError
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContextError
+pub fn radroots_runtime_paths::context::RuntimeContextError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::context::RuntimeContextError
+pub fn radroots_runtime_paths::context::RuntimeContextError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContextError
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContextError
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContextError
+pub enum radroots_runtime_paths::context::RuntimeContextSource
+pub radroots_runtime_paths::context::RuntimeContextSource::BootstrapCli
+pub radroots_runtime_paths::context::RuntimeContextSource::DerivedPath
+pub radroots_runtime_paths::context::RuntimeContextSource::SafeDefault
+pub radroots_runtime_paths::context::RuntimeContextSource::Toml
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSource::clone(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContextSource
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSource::eq(&self, &radroots_runtime_paths::context::RuntimeContextSource) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSource::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContextSource
+impl serde_core::ser::Serialize for radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSource::serialize<__S>(&self, __S) -> core::result::Result<<__S as serde_core::ser::Serializer>::Ok, <__S as serde_core::ser::Serializer>::Error> where __S: serde_core::ser::Serializer
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContextSource
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContextSource
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContextSource
+pub struct radroots_runtime_paths::context::RuntimeContext
+impl radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::instance(&self) -> &radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::context::RuntimeContext::paths(&self) -> &radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::context::RuntimeContext::profile(&self) -> radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::context::RuntimeContext::resolve(&radroots_runtime_paths::roots::RadrootsPathResolver, radroots_runtime_paths::context::RuntimeContextBootstrap, radroots_runtime_paths::identifier::ServiceId, radroots_runtime_paths::identifier::InstanceId) -> core::result::Result<Self, radroots_runtime_paths::context::RuntimeContextError>
+pub fn radroots_runtime_paths::context::RuntimeContext::service(&self) -> &radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::context::RuntimeContext::sources(&self) -> &radroots_runtime_paths::context::RuntimeContextSources
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::clone(&self) -> radroots_runtime_paths::context::RuntimeContext
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContext
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::eq(&self, &radroots_runtime_paths::context::RuntimeContext) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContext
+impl serde_core::ser::Serialize for radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContext
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContext
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContext
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContext
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContext
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContext
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContext
+pub struct radroots_runtime_paths::context::RuntimeContextBootstrap
+impl radroots_runtime_paths::context::RuntimeContextBootstrap
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::new(radroots_runtime_paths::platform::RadrootsPathProfile, core::option::Option<std::path::PathBuf>, radroots_runtime_paths::context::RuntimeContextSource, radroots_runtime_paths::context::RuntimeContextSource) -> core::result::Result<Self, radroots_runtime_paths::context::RuntimeContextError>
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::profile(&self) -> radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContextBootstrap
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::clone(&self) -> radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContextBootstrap
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::eq(&self, &radroots_runtime_paths::context::RuntimeContextBootstrap) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContextBootstrap
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContextBootstrap
+pub struct radroots_runtime_paths::context::RuntimeContextSources
+impl radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::instance(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSources::paths(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSources::profile(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSources::repo_local_root(&self) -> core::option::Option<radroots_runtime_paths::context::RuntimeContextSource>
+pub fn radroots_runtime_paths::context::RuntimeContextSources::service(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::clone(&self) -> radroots_runtime_paths::context::RuntimeContextSources
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContextSources
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::eq(&self, &radroots_runtime_paths::context::RuntimeContextSources) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContextSources
+impl serde_core::ser::Serialize for radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::serialize<__S>(&self, __S) -> core::result::Result<<__S as serde_core::ser::Serializer>::Ok, <__S as serde_core::ser::Serializer>::Error> where __S: serde_core::ser::Serializer
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContextSources
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContextSources
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContextSources
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContextSources
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContextSources
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContextSources
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContextSources
+pub mod radroots_runtime_paths::conventions
+pub enum radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::Empty
+pub radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::InvalidBoundary
+pub radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::InvalidCharacter
+pub radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::TooLong
+pub radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::TooLong::maximum: usize
+impl core::clone::Clone for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::clone(&self) -> radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::cmp::Eq for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::cmp::PartialEq for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::eq(&self, &radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError) -> bool
+impl core::error::Error for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::fmt::Debug for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::Freeze for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::Send for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::Sync for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::Unpin for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub struct radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::admin_socket(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::config(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::state_database(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::state_lock(&self) -> &std::path::Path
+impl core::clone::Clone for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::clone(&self) -> radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::cmp::Eq for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::cmp::PartialEq for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::eq(&self, &radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::Freeze for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::Send for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::Sync for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::Unpin for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub struct radroots_runtime_paths::conventions::ServiceCredentialArtifactName(_)
+impl radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::as_str(&self) -> &str
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::new(impl core::convert::Into<alloc::string::String>) -> core::result::Result<Self, radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError>
+impl core::clone::Clone for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::clone(&self) -> radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::cmp::Eq for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::cmp::Ord for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::cmp(&self, &radroots_runtime_paths::conventions::ServiceCredentialArtifactName) -> core::cmp::Ordering
+impl core::cmp::PartialEq for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::eq(&self, &radroots_runtime_paths::conventions::ServiceCredentialArtifactName) -> bool
+impl core::cmp::PartialOrd for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::partial_cmp(&self, &radroots_runtime_paths::conventions::ServiceCredentialArtifactName) -> core::option::Option<core::cmp::Ordering>
+impl core::convert::AsRef<str> for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::as_ref(&self) -> &str
+impl core::fmt::Debug for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::hash::Hash for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::hash<__H: core::hash::Hasher>(&self, &mut __H)
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::Freeze for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::Send for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::Sync for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::Unpin for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub const radroots_runtime_paths::conventions::DEFAULT_CONFIG_FILE_NAME: &str
+pub const radroots_runtime_paths::conventions::DEFAULT_SHARED_GEONAMES_NAMESPACE: &str
+pub const radroots_runtime_paths::conventions::DEFAULT_SHARED_GEONAMES_NAMESPACE_KIND: &str
+pub const radroots_runtime_paths::conventions::DEFAULT_SHARED_GEONAMES_NAMESPACE_VALUE: &str
+pub const radroots_runtime_paths::conventions::DEFAULT_SHARED_RUNTIME_STORE_DB_FILE_NAME: &str
+pub const radroots_runtime_paths::conventions::DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE: &str
+pub const radroots_runtime_paths::conventions::DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE_KIND: &str
+pub const radroots_runtime_paths::conventions::DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE_VALUE: &str
+pub const radroots_runtime_paths::conventions::SERVICE_ADMIN_SOCKET_FILE_NAME: &str
+pub const radroots_runtime_paths::conventions::SERVICE_CREDENTIAL_ARTIFACT_NAME_MAX_BYTES: usize
+pub const radroots_runtime_paths::conventions::SERVICE_STATE_DATABASE_FILE_NAME: &str
+pub const radroots_runtime_paths::conventions::SERVICE_STATE_LOCK_FILE_NAME: &str
+pub fn radroots_runtime_paths::conventions::default_service_instance_artifacts(&radroots_runtime_paths::service::RadrootsServiceInstancePaths) -> radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::conventions::default_shared_geonames_database_file_name(&str) -> alloc::string::String
+pub fn radroots_runtime_paths::conventions::default_shared_geonames_database_path_from_cache_root(impl core::convert::AsRef<std::path::Path>, &str) -> std::path::PathBuf
+pub fn radroots_runtime_paths::conventions::default_shared_geonames_root_from_cache_root(impl core::convert::AsRef<std::path::Path>) -> std::path::PathBuf
+pub fn radroots_runtime_paths::conventions::default_shared_runtime_store_database_path_from_data_root(impl core::convert::AsRef<std::path::Path>) -> std::path::PathBuf
+pub fn radroots_runtime_paths::conventions::default_shared_runtime_store_database_path_from_shared_accounts_data_root(impl core::convert::AsRef<std::path::Path>) -> core::result::Result<std::path::PathBuf, radroots_runtime_paths::error::RadrootsRuntimePathsError>
+pub fn radroots_runtime_paths::conventions::default_shared_runtime_store_root_from_data_root(impl core::convert::AsRef<std::path::Path>) -> std::path::PathBuf
+pub fn radroots_runtime_paths::conventions::default_shared_runtime_store_root_from_shared_accounts_data_root(impl core::convert::AsRef<std::path::Path>) -> core::result::Result<std::path::PathBuf, radroots_runtime_paths::error::RadrootsRuntimePathsError>
+pub fn radroots_runtime_paths::conventions::service_credential_artifact_path(&radroots_runtime_paths::service::RadrootsServiceInstancePaths, &radroots_runtime_paths::conventions::ServiceCredentialArtifactName) -> std::path::PathBuf
+pub mod radroots_runtime_paths::error
+pub enum radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::InvalidHomeDir
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::InvalidHomeDir::platform: radroots_runtime_paths::platform::RadrootsPlatform
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::InvalidRepoLocalRoot
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::MissingHomeDir
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::MissingHomeDir::platform: radroots_runtime_paths::platform::RadrootsPlatform
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::MissingRepoLocalRoot
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::MissingWindowsUserDirs
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::MissingXdgRuntimeDir
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::SharedAccountsDataRootMissingParent
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::SharedAccountsDataRootMissingParent::path: std::path::PathBuf
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::UnsupportedProfilePlatform
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::UnsupportedProfilePlatform::platform: radroots_runtime_paths::platform::RadrootsPlatform
+pub radroots_runtime_paths::error::RadrootsRuntimePathsError::UnsupportedProfilePlatform::profile: radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::clone::Clone for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub fn radroots_runtime_paths::error::RadrootsRuntimePathsError::clone(&self) -> radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::cmp::Eq for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::cmp::PartialEq for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub fn radroots_runtime_paths::error::RadrootsRuntimePathsError::eq(&self, &radroots_runtime_paths::error::RadrootsRuntimePathsError) -> bool
+impl core::error::Error for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::fmt::Debug for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub fn radroots_runtime_paths::error::RadrootsRuntimePathsError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub fn radroots_runtime_paths::error::RadrootsRuntimePathsError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::Freeze for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::Send for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::Sync for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::Unpin for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub mod radroots_runtime_paths::identifier
+pub enum radroots_runtime_paths::identifier::ServiceIdentityError
+pub radroots_runtime_paths::identifier::ServiceIdentityError::Empty
+pub radroots_runtime_paths::identifier::ServiceIdentityError::Empty::kind: radroots_runtime_paths::identifier::ServiceIdentityKind
+pub radroots_runtime_paths::identifier::ServiceIdentityError::InvalidBoundary
+pub radroots_runtime_paths::identifier::ServiceIdentityError::InvalidBoundary::kind: radroots_runtime_paths::identifier::ServiceIdentityKind
+pub radroots_runtime_paths::identifier::ServiceIdentityError::InvalidCharacter
+pub radroots_runtime_paths::identifier::ServiceIdentityError::InvalidCharacter::kind: radroots_runtime_paths::identifier::ServiceIdentityKind
+pub radroots_runtime_paths::identifier::ServiceIdentityError::TooLong
+pub radroots_runtime_paths::identifier::ServiceIdentityError::TooLong::kind: radroots_runtime_paths::identifier::ServiceIdentityKind
+pub radroots_runtime_paths::identifier::ServiceIdentityError::TooLong::maximum: usize
+impl core::clone::Clone for radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceIdentityError::clone(&self) -> radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::cmp::Eq for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::cmp::PartialEq for radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceIdentityError::eq(&self, &radroots_runtime_paths::identifier::ServiceIdentityError) -> bool
+impl core::error::Error for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::fmt::Debug for radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceIdentityError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceIdentityError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::Freeze for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::Send for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::Sync for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::Unpin for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::identifier::ServiceIdentityError
+pub enum radroots_runtime_paths::identifier::ServiceIdentityKind
+pub radroots_runtime_paths::identifier::ServiceIdentityKind::Instance
+pub radroots_runtime_paths::identifier::ServiceIdentityKind::Service
+impl core::clone::Clone for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub fn radroots_runtime_paths::identifier::ServiceIdentityKind::clone(&self) -> radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::cmp::Eq for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::cmp::PartialEq for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub fn radroots_runtime_paths::identifier::ServiceIdentityKind::eq(&self, &radroots_runtime_paths::identifier::ServiceIdentityKind) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub fn radroots_runtime_paths::identifier::ServiceIdentityKind::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub fn radroots_runtime_paths::identifier::ServiceIdentityKind::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::Freeze for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::Send for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::Sync for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::Unpin for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub struct radroots_runtime_paths::identifier::InstanceId(_)
+impl radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::as_str(&self) -> &str
+pub fn radroots_runtime_paths::identifier::InstanceId::into_string(self) -> alloc::string::String
+pub fn radroots_runtime_paths::identifier::InstanceId::new(impl core::convert::Into<alloc::string::String>) -> core::result::Result<Self, radroots_runtime_paths::identifier::ServiceIdentityError>
+impl core::clone::Clone for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::clone(&self) -> radroots_runtime_paths::identifier::InstanceId
+impl core::cmp::Eq for radroots_runtime_paths::identifier::InstanceId
+impl core::cmp::Ord for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::cmp(&self, &radroots_runtime_paths::identifier::InstanceId) -> core::cmp::Ordering
+impl core::cmp::PartialEq for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::eq(&self, &radroots_runtime_paths::identifier::InstanceId) -> bool
+impl core::cmp::PartialOrd for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::partial_cmp(&self, &radroots_runtime_paths::identifier::InstanceId) -> core::option::Option<core::cmp::Ordering>
+impl core::convert::AsRef<str> for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::as_ref(&self) -> &str
+impl core::convert::From<radroots_runtime_paths::identifier::InstanceId> for alloc::string::String
+pub fn alloc::string::String::from(radroots_runtime_paths::identifier::InstanceId) -> Self
+impl core::convert::TryFrom<alloc::string::String> for radroots_runtime_paths::identifier::InstanceId
+pub type radroots_runtime_paths::identifier::InstanceId::Error = radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::InstanceId::try_from(alloc::string::String) -> core::result::Result<Self, Self::Error>
+impl core::fmt::Debug for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::hash::Hash for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::hash<__H: core::hash::Hasher>(&self, &mut __H)
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::identifier::InstanceId
+impl core::str::traits::FromStr for radroots_runtime_paths::identifier::InstanceId
+pub type radroots_runtime_paths::identifier::InstanceId::Err = radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::InstanceId::from_str(&str) -> core::result::Result<Self, Self::Err>
+impl serde_core::ser::Serialize for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl<'de> serde_core::de::Deserialize<'de> for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de>
+impl core::marker::Freeze for radroots_runtime_paths::identifier::InstanceId
+impl core::marker::Send for radroots_runtime_paths::identifier::InstanceId
+impl core::marker::Sync for radroots_runtime_paths::identifier::InstanceId
+impl core::marker::Unpin for radroots_runtime_paths::identifier::InstanceId
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::identifier::InstanceId
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::identifier::InstanceId
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::identifier::InstanceId
+pub struct radroots_runtime_paths::identifier::ServiceId(_)
+impl radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::as_str(&self) -> &str
+pub fn radroots_runtime_paths::identifier::ServiceId::into_string(self) -> alloc::string::String
+pub fn radroots_runtime_paths::identifier::ServiceId::new(impl core::convert::Into<alloc::string::String>) -> core::result::Result<Self, radroots_runtime_paths::identifier::ServiceIdentityError>
+impl core::clone::Clone for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::clone(&self) -> radroots_runtime_paths::identifier::ServiceId
+impl core::cmp::Eq for radroots_runtime_paths::identifier::ServiceId
+impl core::cmp::Ord for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::cmp(&self, &radroots_runtime_paths::identifier::ServiceId) -> core::cmp::Ordering
+impl core::cmp::PartialEq for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::eq(&self, &radroots_runtime_paths::identifier::ServiceId) -> bool
+impl core::cmp::PartialOrd for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::partial_cmp(&self, &radroots_runtime_paths::identifier::ServiceId) -> core::option::Option<core::cmp::Ordering>
+impl core::convert::AsRef<str> for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::as_ref(&self) -> &str
+impl core::convert::From<radroots_runtime_paths::identifier::ServiceId> for alloc::string::String
+pub fn alloc::string::String::from(radroots_runtime_paths::identifier::ServiceId) -> Self
+impl core::convert::TryFrom<alloc::string::String> for radroots_runtime_paths::identifier::ServiceId
+pub type radroots_runtime_paths::identifier::ServiceId::Error = radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceId::try_from(alloc::string::String) -> core::result::Result<Self, Self::Error>
+impl core::fmt::Debug for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::hash::Hash for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::hash<__H: core::hash::Hasher>(&self, &mut __H)
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::identifier::ServiceId
+impl core::str::traits::FromStr for radroots_runtime_paths::identifier::ServiceId
+pub type radroots_runtime_paths::identifier::ServiceId::Err = radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceId::from_str(&str) -> core::result::Result<Self, Self::Err>
+impl serde_core::ser::Serialize for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl<'de> serde_core::de::Deserialize<'de> for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de>
+impl core::marker::Freeze for radroots_runtime_paths::identifier::ServiceId
+impl core::marker::Send for radroots_runtime_paths::identifier::ServiceId
+impl core::marker::Sync for radroots_runtime_paths::identifier::ServiceId
+impl core::marker::Unpin for radroots_runtime_paths::identifier::ServiceId
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::identifier::ServiceId
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::identifier::ServiceId
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::identifier::ServiceId
+pub const radroots_runtime_paths::identifier::INSTANCE_ID_MAX_BYTES: usize
+pub const radroots_runtime_paths::identifier::SERVICE_ID_MAX_BYTES: usize
+pub mod radroots_runtime_paths::platform
+pub enum radroots_runtime_paths::platform::RadrootsPathProfile
+pub radroots_runtime_paths::platform::RadrootsPathProfile::InteractiveUser
+pub radroots_runtime_paths::platform::RadrootsPathProfile::MobileNative
+pub radroots_runtime_paths::platform::RadrootsPathProfile::RepoLocal
+pub radroots_runtime_paths::platform::RadrootsPathProfile::ServiceHost
+impl core::clone::Clone for radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::platform::RadrootsPathProfile::clone(&self) -> radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::cmp::Eq for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::cmp::PartialEq for radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::platform::RadrootsPathProfile::eq(&self, &radroots_runtime_paths::platform::RadrootsPathProfile) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::platform::RadrootsPathProfile::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::platform::RadrootsPathProfile::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::Freeze for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::Send for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::Sync for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::Unpin for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::platform::RadrootsPathProfile
+pub enum radroots_runtime_paths::platform::RadrootsPlatform
+pub radroots_runtime_paths::platform::RadrootsPlatform::Android
+pub radroots_runtime_paths::platform::RadrootsPlatform::Ios
+pub radroots_runtime_paths::platform::RadrootsPlatform::Linux
+pub radroots_runtime_paths::platform::RadrootsPlatform::Macos
+pub radroots_runtime_paths::platform::RadrootsPlatform::Other
+pub radroots_runtime_paths::platform::RadrootsPlatform::Windows
+impl radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::current() -> Self
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::is_unix_like(self) -> bool
+impl core::clone::Clone for radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::clone(&self) -> radroots_runtime_paths::platform::RadrootsPlatform
+impl core::cmp::Eq for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::cmp::PartialEq for radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::eq(&self, &radroots_runtime_paths::platform::RadrootsPlatform) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::Freeze for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::Send for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::Sync for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::Unpin for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::platform::RadrootsPlatform
+pub struct radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub radroots_runtime_paths::platform::RadrootsHostEnvironment::appdata_dir: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::platform::RadrootsHostEnvironment::home_dir: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::platform::RadrootsHostEnvironment::localappdata_dir: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::platform::RadrootsHostEnvironment::xdg_cache_home: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::platform::RadrootsHostEnvironment::xdg_config_home: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::platform::RadrootsHostEnvironment::xdg_data_home: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::platform::RadrootsHostEnvironment::xdg_runtime_dir: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::platform::RadrootsHostEnvironment::xdg_state_home: core::option::Option<std::path::PathBuf>
+impl core::clone::Clone for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub fn radroots_runtime_paths::platform::RadrootsHostEnvironment::clone(&self) -> radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::cmp::Eq for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::cmp::PartialEq for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub fn radroots_runtime_paths::platform::RadrootsHostEnvironment::eq(&self, &radroots_runtime_paths::platform::RadrootsHostEnvironment) -> bool
+impl core::default::Default for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub fn radroots_runtime_paths::platform::RadrootsHostEnvironment::default() -> radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::fmt::Debug for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub fn radroots_runtime_paths::platform::RadrootsHostEnvironment::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::Freeze for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::Send for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::Sync for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::Unpin for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub mod radroots_runtime_paths::roots
+pub struct radroots_runtime_paths::roots::RadrootsPathResolver
+impl radroots_runtime_paths::roots::RadrootsPathResolver
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::new(radroots_runtime_paths::platform::RadrootsPlatform, radroots_runtime_paths::platform::RadrootsHostEnvironment) -> Self
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::platform(&self) -> radroots_runtime_paths::platform::RadrootsPlatform
+impl core::clone::Clone for radroots_runtime_paths::roots::RadrootsPathResolver
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::clone(&self) -> radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::cmp::Eq for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::cmp::PartialEq for radroots_runtime_paths::roots::RadrootsPathResolver
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::eq(&self, &radroots_runtime_paths::roots::RadrootsPathResolver) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::roots::RadrootsPathResolver
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::Freeze for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::Send for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::Sync for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::Unpin for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::roots::RadrootsPathResolver
+pub mod radroots_runtime_paths::service
+pub struct radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::cache(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::config(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::logs(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::run(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::secrets(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::state(&self) -> &std::path::Path
+impl core::clone::Clone for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::clone(&self) -> radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::cmp::Eq for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::cmp::PartialEq for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::eq(&self, &radroots_runtime_paths::service::RadrootsServiceInstancePaths) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::Freeze for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::Send for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::Sync for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::Unpin for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub enum radroots_runtime_paths::RadrootsPathProfile
+pub radroots_runtime_paths::RadrootsPathProfile::InteractiveUser
+pub radroots_runtime_paths::RadrootsPathProfile::MobileNative
+pub radroots_runtime_paths::RadrootsPathProfile::RepoLocal
+pub radroots_runtime_paths::RadrootsPathProfile::ServiceHost
+impl core::clone::Clone for radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::platform::RadrootsPathProfile::clone(&self) -> radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::cmp::Eq for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::cmp::PartialEq for radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::platform::RadrootsPathProfile::eq(&self, &radroots_runtime_paths::platform::RadrootsPathProfile) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::platform::RadrootsPathProfile::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::platform::RadrootsPathProfile::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::Freeze for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::Send for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::Sync for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::Unpin for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::platform::RadrootsPathProfile
+pub enum radroots_runtime_paths::RadrootsPlatform
+pub radroots_runtime_paths::RadrootsPlatform::Android
+pub radroots_runtime_paths::RadrootsPlatform::Ios
+pub radroots_runtime_paths::RadrootsPlatform::Linux
+pub radroots_runtime_paths::RadrootsPlatform::Macos
+pub radroots_runtime_paths::RadrootsPlatform::Other
+pub radroots_runtime_paths::RadrootsPlatform::Windows
+impl radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::current() -> Self
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::is_unix_like(self) -> bool
+impl core::clone::Clone for radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::clone(&self) -> radroots_runtime_paths::platform::RadrootsPlatform
+impl core::cmp::Eq for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::cmp::PartialEq for radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::eq(&self, &radroots_runtime_paths::platform::RadrootsPlatform) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::platform::RadrootsPlatform
+pub fn radroots_runtime_paths::platform::RadrootsPlatform::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::Freeze for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::Send for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::Sync for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::Unpin for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::platform::RadrootsPlatform
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::platform::RadrootsPlatform
+pub enum radroots_runtime_paths::RadrootsRuntimePathsError
+pub radroots_runtime_paths::RadrootsRuntimePathsError::InvalidHomeDir
+pub radroots_runtime_paths::RadrootsRuntimePathsError::InvalidHomeDir::platform: radroots_runtime_paths::platform::RadrootsPlatform
+pub radroots_runtime_paths::RadrootsRuntimePathsError::InvalidRepoLocalRoot
+pub radroots_runtime_paths::RadrootsRuntimePathsError::MissingHomeDir
+pub radroots_runtime_paths::RadrootsRuntimePathsError::MissingHomeDir::platform: radroots_runtime_paths::platform::RadrootsPlatform
+pub radroots_runtime_paths::RadrootsRuntimePathsError::MissingRepoLocalRoot
+pub radroots_runtime_paths::RadrootsRuntimePathsError::MissingWindowsUserDirs
+pub radroots_runtime_paths::RadrootsRuntimePathsError::MissingXdgRuntimeDir
+pub radroots_runtime_paths::RadrootsRuntimePathsError::SharedAccountsDataRootMissingParent
+pub radroots_runtime_paths::RadrootsRuntimePathsError::SharedAccountsDataRootMissingParent::path: std::path::PathBuf
+pub radroots_runtime_paths::RadrootsRuntimePathsError::UnsupportedProfilePlatform
+pub radroots_runtime_paths::RadrootsRuntimePathsError::UnsupportedProfilePlatform::platform: radroots_runtime_paths::platform::RadrootsPlatform
+pub radroots_runtime_paths::RadrootsRuntimePathsError::UnsupportedProfilePlatform::profile: radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::clone::Clone for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub fn radroots_runtime_paths::error::RadrootsRuntimePathsError::clone(&self) -> radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::cmp::Eq for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::cmp::PartialEq for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub fn radroots_runtime_paths::error::RadrootsRuntimePathsError::eq(&self, &radroots_runtime_paths::error::RadrootsRuntimePathsError) -> bool
+impl core::error::Error for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::fmt::Debug for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub fn radroots_runtime_paths::error::RadrootsRuntimePathsError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub fn radroots_runtime_paths::error::RadrootsRuntimePathsError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::Freeze for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::Send for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::Sync for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::Unpin for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::error::RadrootsRuntimePathsError
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::error::RadrootsRuntimePathsError
+pub enum radroots_runtime_paths::RuntimeContextError
+pub radroots_runtime_paths::RuntimeContextError::InvalidBootstrapBinding
+pub radroots_runtime_paths::RuntimeContextError::PathSelection
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContextError
+pub fn radroots_runtime_paths::context::RuntimeContextError::clone(&self) -> radroots_runtime_paths::context::RuntimeContextError
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContextError
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContextError
+pub fn radroots_runtime_paths::context::RuntimeContextError::eq(&self, &radroots_runtime_paths::context::RuntimeContextError) -> bool
+impl core::error::Error for radroots_runtime_paths::context::RuntimeContextError
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContextError
+pub fn radroots_runtime_paths::context::RuntimeContextError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::context::RuntimeContextError
+pub fn radroots_runtime_paths::context::RuntimeContextError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContextError
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContextError
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContextError
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContextError
+pub enum radroots_runtime_paths::RuntimeContextSource
+pub radroots_runtime_paths::RuntimeContextSource::BootstrapCli
+pub radroots_runtime_paths::RuntimeContextSource::DerivedPath
+pub radroots_runtime_paths::RuntimeContextSource::SafeDefault
+pub radroots_runtime_paths::RuntimeContextSource::Toml
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSource::clone(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContextSource
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSource::eq(&self, &radroots_runtime_paths::context::RuntimeContextSource) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSource::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContextSource
+impl serde_core::ser::Serialize for radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSource::serialize<__S>(&self, __S) -> core::result::Result<<__S as serde_core::ser::Serializer>::Ok, <__S as serde_core::ser::Serializer>::Error> where __S: serde_core::ser::Serializer
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContextSource
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContextSource
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContextSource
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContextSource
+pub enum radroots_runtime_paths::ServiceCredentialArtifactNameError
+pub radroots_runtime_paths::ServiceCredentialArtifactNameError::Empty
+pub radroots_runtime_paths::ServiceCredentialArtifactNameError::InvalidBoundary
+pub radroots_runtime_paths::ServiceCredentialArtifactNameError::InvalidCharacter
+pub radroots_runtime_paths::ServiceCredentialArtifactNameError::TooLong
+pub radroots_runtime_paths::ServiceCredentialArtifactNameError::TooLong::maximum: usize
+impl core::clone::Clone for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::clone(&self) -> radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::cmp::Eq for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::cmp::PartialEq for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::eq(&self, &radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError) -> bool
+impl core::error::Error for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::fmt::Debug for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::Freeze for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::Send for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::Sync for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::Unpin for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError
+pub enum radroots_runtime_paths::ServiceIdentityError
+pub radroots_runtime_paths::ServiceIdentityError::Empty
+pub radroots_runtime_paths::ServiceIdentityError::Empty::kind: radroots_runtime_paths::identifier::ServiceIdentityKind
+pub radroots_runtime_paths::ServiceIdentityError::InvalidBoundary
+pub radroots_runtime_paths::ServiceIdentityError::InvalidBoundary::kind: radroots_runtime_paths::identifier::ServiceIdentityKind
+pub radroots_runtime_paths::ServiceIdentityError::InvalidCharacter
+pub radroots_runtime_paths::ServiceIdentityError::InvalidCharacter::kind: radroots_runtime_paths::identifier::ServiceIdentityKind
+pub radroots_runtime_paths::ServiceIdentityError::TooLong
+pub radroots_runtime_paths::ServiceIdentityError::TooLong::kind: radroots_runtime_paths::identifier::ServiceIdentityKind
+pub radroots_runtime_paths::ServiceIdentityError::TooLong::maximum: usize
+impl core::clone::Clone for radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceIdentityError::clone(&self) -> radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::cmp::Eq for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::cmp::PartialEq for radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceIdentityError::eq(&self, &radroots_runtime_paths::identifier::ServiceIdentityError) -> bool
+impl core::error::Error for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::fmt::Debug for radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceIdentityError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceIdentityError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::Freeze for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::Send for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::Sync for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::Unpin for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::identifier::ServiceIdentityError
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::identifier::ServiceIdentityError
+pub enum radroots_runtime_paths::ServiceIdentityKind
+pub radroots_runtime_paths::ServiceIdentityKind::Instance
+pub radroots_runtime_paths::ServiceIdentityKind::Service
+impl core::clone::Clone for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub fn radroots_runtime_paths::identifier::ServiceIdentityKind::clone(&self) -> radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::cmp::Eq for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::cmp::PartialEq for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub fn radroots_runtime_paths::identifier::ServiceIdentityKind::eq(&self, &radroots_runtime_paths::identifier::ServiceIdentityKind) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub fn radroots_runtime_paths::identifier::ServiceIdentityKind::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub fn radroots_runtime_paths::identifier::ServiceIdentityKind::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::Copy for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::Freeze for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::Send for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::Sync for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::Unpin for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::identifier::ServiceIdentityKind
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::identifier::ServiceIdentityKind
+pub struct radroots_runtime_paths::InstanceId(_)
+impl radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::as_str(&self) -> &str
+pub fn radroots_runtime_paths::identifier::InstanceId::into_string(self) -> alloc::string::String
+pub fn radroots_runtime_paths::identifier::InstanceId::new(impl core::convert::Into<alloc::string::String>) -> core::result::Result<Self, radroots_runtime_paths::identifier::ServiceIdentityError>
+impl core::clone::Clone for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::clone(&self) -> radroots_runtime_paths::identifier::InstanceId
+impl core::cmp::Eq for radroots_runtime_paths::identifier::InstanceId
+impl core::cmp::Ord for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::cmp(&self, &radroots_runtime_paths::identifier::InstanceId) -> core::cmp::Ordering
+impl core::cmp::PartialEq for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::eq(&self, &radroots_runtime_paths::identifier::InstanceId) -> bool
+impl core::cmp::PartialOrd for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::partial_cmp(&self, &radroots_runtime_paths::identifier::InstanceId) -> core::option::Option<core::cmp::Ordering>
+impl core::convert::AsRef<str> for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::as_ref(&self) -> &str
+impl core::convert::From<radroots_runtime_paths::identifier::InstanceId> for alloc::string::String
+pub fn alloc::string::String::from(radroots_runtime_paths::identifier::InstanceId) -> Self
+impl core::convert::TryFrom<alloc::string::String> for radroots_runtime_paths::identifier::InstanceId
+pub type radroots_runtime_paths::identifier::InstanceId::Error = radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::InstanceId::try_from(alloc::string::String) -> core::result::Result<Self, Self::Error>
+impl core::fmt::Debug for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::hash::Hash for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::hash<__H: core::hash::Hasher>(&self, &mut __H)
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::identifier::InstanceId
+impl core::str::traits::FromStr for radroots_runtime_paths::identifier::InstanceId
+pub type radroots_runtime_paths::identifier::InstanceId::Err = radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::InstanceId::from_str(&str) -> core::result::Result<Self, Self::Err>
+impl serde_core::ser::Serialize for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl<'de> serde_core::de::Deserialize<'de> for radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::identifier::InstanceId::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de>
+impl core::marker::Freeze for radroots_runtime_paths::identifier::InstanceId
+impl core::marker::Send for radroots_runtime_paths::identifier::InstanceId
+impl core::marker::Sync for radroots_runtime_paths::identifier::InstanceId
+impl core::marker::Unpin for radroots_runtime_paths::identifier::InstanceId
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::identifier::InstanceId
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::identifier::InstanceId
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::identifier::InstanceId
+pub struct radroots_runtime_paths::RadrootsHostEnvironment
+pub radroots_runtime_paths::RadrootsHostEnvironment::appdata_dir: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::RadrootsHostEnvironment::home_dir: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::RadrootsHostEnvironment::localappdata_dir: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::RadrootsHostEnvironment::xdg_cache_home: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::RadrootsHostEnvironment::xdg_config_home: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::RadrootsHostEnvironment::xdg_data_home: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::RadrootsHostEnvironment::xdg_runtime_dir: core::option::Option<std::path::PathBuf>
+pub radroots_runtime_paths::RadrootsHostEnvironment::xdg_state_home: core::option::Option<std::path::PathBuf>
+impl core::clone::Clone for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub fn radroots_runtime_paths::platform::RadrootsHostEnvironment::clone(&self) -> radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::cmp::Eq for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::cmp::PartialEq for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub fn radroots_runtime_paths::platform::RadrootsHostEnvironment::eq(&self, &radroots_runtime_paths::platform::RadrootsHostEnvironment) -> bool
+impl core::default::Default for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub fn radroots_runtime_paths::platform::RadrootsHostEnvironment::default() -> radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::fmt::Debug for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub fn radroots_runtime_paths::platform::RadrootsHostEnvironment::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::Freeze for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::Send for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::Sync for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::Unpin for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::platform::RadrootsHostEnvironment
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::platform::RadrootsHostEnvironment
+pub struct radroots_runtime_paths::RadrootsPathResolver
+impl radroots_runtime_paths::roots::RadrootsPathResolver
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::new(radroots_runtime_paths::platform::RadrootsPlatform, radroots_runtime_paths::platform::RadrootsHostEnvironment) -> Self
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::platform(&self) -> radroots_runtime_paths::platform::RadrootsPlatform
+impl core::clone::Clone for radroots_runtime_paths::roots::RadrootsPathResolver
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::clone(&self) -> radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::cmp::Eq for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::cmp::PartialEq for radroots_runtime_paths::roots::RadrootsPathResolver
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::eq(&self, &radroots_runtime_paths::roots::RadrootsPathResolver) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::roots::RadrootsPathResolver
+pub fn radroots_runtime_paths::roots::RadrootsPathResolver::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::Freeze for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::Send for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::Sync for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::Unpin for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::roots::RadrootsPathResolver
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::roots::RadrootsPathResolver
+pub struct radroots_runtime_paths::RadrootsServiceInstanceArtifacts
+impl radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::admin_socket(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::config(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::state_database(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::state_lock(&self) -> &std::path::Path
+impl core::clone::Clone for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::clone(&self) -> radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::cmp::Eq for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::cmp::PartialEq for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::eq(&self, &radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::Freeze for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::Send for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::Sync for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::Unpin for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub struct radroots_runtime_paths::RadrootsServiceInstancePaths
+impl radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::cache(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::config(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::logs(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::run(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::secrets(&self) -> &std::path::Path
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::state(&self) -> &std::path::Path
+impl core::clone::Clone for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::clone(&self) -> radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::cmp::Eq for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::cmp::PartialEq for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::eq(&self, &radroots_runtime_paths::service::RadrootsServiceInstancePaths) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::service::RadrootsServiceInstancePaths::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::Freeze for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::Send for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::Sync for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::Unpin for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub struct radroots_runtime_paths::RuntimeContext
+impl radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::instance(&self) -> &radroots_runtime_paths::identifier::InstanceId
+pub fn radroots_runtime_paths::context::RuntimeContext::paths(&self) -> &radroots_runtime_paths::service::RadrootsServiceInstancePaths
+pub fn radroots_runtime_paths::context::RuntimeContext::profile(&self) -> radroots_runtime_paths::platform::RadrootsPathProfile
+pub fn radroots_runtime_paths::context::RuntimeContext::resolve(&radroots_runtime_paths::roots::RadrootsPathResolver, radroots_runtime_paths::context::RuntimeContextBootstrap, radroots_runtime_paths::identifier::ServiceId, radroots_runtime_paths::identifier::InstanceId) -> core::result::Result<Self, radroots_runtime_paths::context::RuntimeContextError>
+pub fn radroots_runtime_paths::context::RuntimeContext::service(&self) -> &radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::context::RuntimeContext::sources(&self) -> &radroots_runtime_paths::context::RuntimeContextSources
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::clone(&self) -> radroots_runtime_paths::context::RuntimeContext
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContext
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::eq(&self, &radroots_runtime_paths::context::RuntimeContext) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContext
+impl serde_core::ser::Serialize for radroots_runtime_paths::context::RuntimeContext
+pub fn radroots_runtime_paths::context::RuntimeContext::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContext
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContext
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContext
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContext
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContext
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContext
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContext
+pub struct radroots_runtime_paths::RuntimeContextBootstrap
+impl radroots_runtime_paths::context::RuntimeContextBootstrap
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::new(radroots_runtime_paths::platform::RadrootsPathProfile, core::option::Option<std::path::PathBuf>, radroots_runtime_paths::context::RuntimeContextSource, radroots_runtime_paths::context::RuntimeContextSource) -> core::result::Result<Self, radroots_runtime_paths::context::RuntimeContextError>
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::profile(&self) -> radroots_runtime_paths::platform::RadrootsPathProfile
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContextBootstrap
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::clone(&self) -> radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContextBootstrap
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::eq(&self, &radroots_runtime_paths::context::RuntimeContextBootstrap) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContextBootstrap
+pub fn radroots_runtime_paths::context::RuntimeContextBootstrap::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContextBootstrap
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContextBootstrap
+pub struct radroots_runtime_paths::RuntimeContextSources
+impl radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::instance(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSources::paths(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSources::profile(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+pub fn radroots_runtime_paths::context::RuntimeContextSources::repo_local_root(&self) -> core::option::Option<radroots_runtime_paths::context::RuntimeContextSource>
+pub fn radroots_runtime_paths::context::RuntimeContextSources::service(&self) -> radroots_runtime_paths::context::RuntimeContextSource
+impl core::clone::Clone for radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::clone(&self) -> radroots_runtime_paths::context::RuntimeContextSources
+impl core::cmp::Eq for radroots_runtime_paths::context::RuntimeContextSources
+impl core::cmp::PartialEq for radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::eq(&self, &radroots_runtime_paths::context::RuntimeContextSources) -> bool
+impl core::fmt::Debug for radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::context::RuntimeContextSources
+impl serde_core::ser::Serialize for radroots_runtime_paths::context::RuntimeContextSources
+pub fn radroots_runtime_paths::context::RuntimeContextSources::serialize<__S>(&self, __S) -> core::result::Result<<__S as serde_core::ser::Serializer>::Ok, <__S as serde_core::ser::Serializer>::Error> where __S: serde_core::ser::Serializer
+impl core::marker::Freeze for radroots_runtime_paths::context::RuntimeContextSources
+impl core::marker::Send for radroots_runtime_paths::context::RuntimeContextSources
+impl core::marker::Sync for radroots_runtime_paths::context::RuntimeContextSources
+impl core::marker::Unpin for radroots_runtime_paths::context::RuntimeContextSources
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::context::RuntimeContextSources
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::context::RuntimeContextSources
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::context::RuntimeContextSources
+pub struct radroots_runtime_paths::ServiceCredentialArtifactName(_)
+impl radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::as_str(&self) -> &str
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::new(impl core::convert::Into<alloc::string::String>) -> core::result::Result<Self, radroots_runtime_paths::conventions::ServiceCredentialArtifactNameError>
+impl core::clone::Clone for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::clone(&self) -> radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::cmp::Eq for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::cmp::Ord for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::cmp(&self, &radroots_runtime_paths::conventions::ServiceCredentialArtifactName) -> core::cmp::Ordering
+impl core::cmp::PartialEq for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::eq(&self, &radroots_runtime_paths::conventions::ServiceCredentialArtifactName) -> bool
+impl core::cmp::PartialOrd for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::partial_cmp(&self, &radroots_runtime_paths::conventions::ServiceCredentialArtifactName) -> core::option::Option<core::cmp::Ordering>
+impl core::convert::AsRef<str> for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::as_ref(&self) -> &str
+impl core::fmt::Debug for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::hash::Hash for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub fn radroots_runtime_paths::conventions::ServiceCredentialArtifactName::hash<__H: core::hash::Hasher>(&self, &mut __H)
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::Freeze for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::Send for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::Sync for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::Unpin for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::conventions::ServiceCredentialArtifactName
+pub struct radroots_runtime_paths::ServiceId(_)
+impl radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::as_str(&self) -> &str
+pub fn radroots_runtime_paths::identifier::ServiceId::into_string(self) -> alloc::string::String
+pub fn radroots_runtime_paths::identifier::ServiceId::new(impl core::convert::Into<alloc::string::String>) -> core::result::Result<Self, radroots_runtime_paths::identifier::ServiceIdentityError>
+impl core::clone::Clone for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::clone(&self) -> radroots_runtime_paths::identifier::ServiceId
+impl core::cmp::Eq for radroots_runtime_paths::identifier::ServiceId
+impl core::cmp::Ord for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::cmp(&self, &radroots_runtime_paths::identifier::ServiceId) -> core::cmp::Ordering
+impl core::cmp::PartialEq for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::eq(&self, &radroots_runtime_paths::identifier::ServiceId) -> bool
+impl core::cmp::PartialOrd for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::partial_cmp(&self, &radroots_runtime_paths::identifier::ServiceId) -> core::option::Option<core::cmp::Ordering>
+impl core::convert::AsRef<str> for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::as_ref(&self) -> &str
+impl core::convert::From<radroots_runtime_paths::identifier::ServiceId> for alloc::string::String
+pub fn alloc::string::String::from(radroots_runtime_paths::identifier::ServiceId) -> Self
+impl core::convert::TryFrom<alloc::string::String> for radroots_runtime_paths::identifier::ServiceId
+pub type radroots_runtime_paths::identifier::ServiceId::Error = radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceId::try_from(alloc::string::String) -> core::result::Result<Self, Self::Error>
+impl core::fmt::Debug for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::hash::Hash for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::hash<__H: core::hash::Hasher>(&self, &mut __H)
+impl core::marker::StructuralPartialEq for radroots_runtime_paths::identifier::ServiceId
+impl core::str::traits::FromStr for radroots_runtime_paths::identifier::ServiceId
+pub type radroots_runtime_paths::identifier::ServiceId::Err = radroots_runtime_paths::identifier::ServiceIdentityError
+pub fn radroots_runtime_paths::identifier::ServiceId::from_str(&str) -> core::result::Result<Self, Self::Err>
+impl serde_core::ser::Serialize for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl<'de> serde_core::de::Deserialize<'de> for radroots_runtime_paths::identifier::ServiceId
+pub fn radroots_runtime_paths::identifier::ServiceId::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de>
+impl core::marker::Freeze for radroots_runtime_paths::identifier::ServiceId
+impl core::marker::Send for radroots_runtime_paths::identifier::ServiceId
+impl core::marker::Sync for radroots_runtime_paths::identifier::ServiceId
+impl core::marker::Unpin for radroots_runtime_paths::identifier::ServiceId
+impl core::marker::UnsafeUnpin for radroots_runtime_paths::identifier::ServiceId
+impl core::panic::unwind_safe::RefUnwindSafe for radroots_runtime_paths::identifier::ServiceId
+impl core::panic::unwind_safe::UnwindSafe for radroots_runtime_paths::identifier::ServiceId
+pub const radroots_runtime_paths::DEFAULT_CONFIG_FILE_NAME: &str
+pub const radroots_runtime_paths::DEFAULT_SHARED_GEONAMES_NAMESPACE: &str
+pub const radroots_runtime_paths::DEFAULT_SHARED_GEONAMES_NAMESPACE_KIND: &str
+pub const radroots_runtime_paths::DEFAULT_SHARED_GEONAMES_NAMESPACE_VALUE: &str
+pub const radroots_runtime_paths::DEFAULT_SHARED_RUNTIME_STORE_DB_FILE_NAME: &str
+pub const radroots_runtime_paths::DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE: &str
+pub const radroots_runtime_paths::DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE_KIND: &str
+pub const radroots_runtime_paths::DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE_VALUE: &str
+pub const radroots_runtime_paths::INSTANCE_ID_MAX_BYTES: usize
+pub const radroots_runtime_paths::SERVICE_ADMIN_SOCKET_FILE_NAME: &str
+pub const radroots_runtime_paths::SERVICE_CREDENTIAL_ARTIFACT_NAME_MAX_BYTES: usize
+pub const radroots_runtime_paths::SERVICE_ID_MAX_BYTES: usize
+pub const radroots_runtime_paths::SERVICE_STATE_DATABASE_FILE_NAME: &str
+pub const radroots_runtime_paths::SERVICE_STATE_LOCK_FILE_NAME: &str
+pub fn radroots_runtime_paths::default_service_instance_artifacts(&radroots_runtime_paths::service::RadrootsServiceInstancePaths) -> radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub fn radroots_runtime_paths::default_shared_geonames_database_file_name(&str) -> alloc::string::String
+pub fn radroots_runtime_paths::default_shared_geonames_database_path_from_cache_root(impl core::convert::AsRef<std::path::Path>, &str) -> std::path::PathBuf
+pub fn radroots_runtime_paths::default_shared_geonames_root_from_cache_root(impl core::convert::AsRef<std::path::Path>) -> std::path::PathBuf
+pub fn radroots_runtime_paths::default_shared_runtime_store_database_path_from_data_root(impl core::convert::AsRef<std::path::Path>) -> std::path::PathBuf
+pub fn radroots_runtime_paths::default_shared_runtime_store_database_path_from_shared_accounts_data_root(impl core::convert::AsRef<std::path::Path>) -> core::result::Result<std::path::PathBuf, radroots_runtime_paths::error::RadrootsRuntimePathsError>
+pub fn radroots_runtime_paths::default_shared_runtime_store_root_from_data_root(impl core::convert::AsRef<std::path::Path>) -> std::path::PathBuf
+pub fn radroots_runtime_paths::default_shared_runtime_store_root_from_shared_accounts_data_root(impl core::convert::AsRef<std::path::Path>) -> core::result::Result<std::path::PathBuf, radroots_runtime_paths::error::RadrootsRuntimePathsError>
+pub fn radroots_runtime_paths::service_credential_artifact_path(&radroots_runtime_paths::service::RadrootsServiceInstancePaths, &radroots_runtime_paths::conventions::ServiceCredentialArtifactName) -> std::path::PathBuf
diff --git a/crates/runtime_paths/README b/crates/runtime_paths/README
@@ -1,18 +1,25 @@
# radroots_runtime_paths
-This is the README for `radroots_runtime_paths`, which provides canonical
-runtime path selection and contract helpers for the `radroots` core libraries.
+This is the README for `radroots_runtime_paths`, which provides canonical,
+typed runtime paths for the `radroots` core libraries.
## Overview
- * default file-name and bootstrap-path helpers for local runtime layouts;
- * platform, host-environment, namespace, and path-profile types for path
- decisions;
- * validated service and instance identifiers for canonical service paths;
- * resolver, override, and runtime-selection helpers that produce structured
- `RadrootsPaths` outputs;
- * service and app contract helpers for active profile, override, and root
- selection reporting.
+ * validated service and instance identifiers for the sole canonical
+ `services/<service>/<instance>` namespace;
+ * an injected platform, host-environment, and profile resolver with no ambient
+ process-environment constructor;
+ * a sealed `RuntimeContext` as the only public service-instance path
+ construction boundary;
+ * non-forgeable service path and common-artifact views with immutable
+ accessors; and
+ * pure shared geonames and runtime-store path helpers that do not participate
+ in service-instance path selection.
+
+The former generic app/service/worker/shared namespace, raw root containers,
+path overrides, process-environment selectors, and bootstrap path helpers are
+intentionally removed. Callers must construct typed bootstrap provenance and
+resolve a `RuntimeContext` from an explicitly injected resolver.
## Copyright
diff --git a/crates/runtime_paths/src/context.rs b/crates/runtime_paths/src/context.rs
@@ -7,8 +7,7 @@ use serde::{Serialize, Serializer, ser::SerializeStruct};
use thiserror::Error;
use crate::{
- InstanceId, RadrootsPathOverrides, RadrootsPathProfile, RadrootsPathResolver,
- RadrootsServiceInstancePaths, ServiceId, default_service_instance_paths,
+ InstanceId, RadrootsPathProfile, RadrootsPathResolver, RadrootsServiceInstancePaths, ServiceId,
};
/// Closed provenance vocabulary for effective runtime configuration.
@@ -158,18 +157,10 @@ impl RuntimeContext {
service: ServiceId,
instance: InstanceId,
) -> Result<Self, RuntimeContextError> {
- let overrides = match bootstrap.repo_local_root.as_ref() {
- Some(root) => RadrootsPathOverrides::repo_local(root),
- None => RadrootsPathOverrides::default(),
- };
- let paths = default_service_instance_paths(
- resolver,
- bootstrap.profile,
- &overrides,
- &service,
- &instance,
- )
- .map_err(|_| RuntimeContextError::PathSelection)?;
+ let roots = resolver
+ .resolve(bootstrap.profile, bootstrap.repo_local_root.as_deref())
+ .map_err(|_| RuntimeContextError::PathSelection)?;
+ let paths = RadrootsServiceInstancePaths::from_resolved_roots(&roots, &service, &instance);
let sources = RuntimeContextSources {
service: RuntimeContextSource::SafeDefault,
instance: bootstrap.instance_source,
@@ -268,6 +259,10 @@ mod tests {
};
fn repo_local_context(base: PathBuf) -> RuntimeContext {
+ repo_local_context_for(base, "myc", "primary")
+ }
+
+ fn repo_local_context_for(base: PathBuf, service: &str, instance: &str) -> RuntimeContext {
RuntimeContext::resolve(
&RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default()),
RuntimeContextBootstrap::new(
@@ -277,10 +272,271 @@ mod tests {
RuntimeContextSource::BootstrapCli,
)
.expect("bootstrap"),
+ ServiceId::new(service).expect("service"),
+ InstanceId::new(instance).expect("instance"),
+ )
+ .expect("runtime context")
+ }
+
+ #[test]
+ fn one_repo_local_base_derives_exact_noncolliding_service_instances() {
+ let base = PathBuf::from("/repo/.local/radroots");
+ let mut configs = Vec::new();
+
+ for (service, instance) in [("myc", "primary"), ("myc", "secondary"), ("rhi", "default")] {
+ let context = repo_local_context_for(base.clone(), service, instance);
+ let suffix = PathBuf::from("services").join(service).join(instance);
+ assert_eq!(context.paths().config(), base.join("config").join(&suffix));
+ assert_eq!(context.paths().state(), base.join("data").join(&suffix));
+ assert_eq!(context.paths().cache(), base.join("cache").join(&suffix));
+ assert_eq!(context.paths().logs(), base.join("logs").join(&suffix));
+ assert_eq!(context.paths().run(), base.join("run").join(&suffix));
+ assert_eq!(
+ context.paths().secrets(),
+ base.join("secrets").join(&suffix)
+ );
+ configs.push(context.paths().config().to_path_buf());
+ }
+
+ configs.sort();
+ configs.dedup();
+ assert_eq!(configs.len(), 3);
+ }
+
+ #[test]
+ fn retained_macos_and_windows_profiles_derive_exact_context_paths() {
+ let macos = RuntimeContext::resolve(
+ &RadrootsPathResolver::new(
+ RadrootsPlatform::Macos,
+ RadrootsHostEnvironment {
+ home_dir: Some(PathBuf::from("/Users/treesap")),
+ ..RadrootsHostEnvironment::default()
+ },
+ ),
+ RuntimeContextBootstrap::new(
+ RadrootsPathProfile::InteractiveUser,
+ None,
+ RuntimeContextSource::SafeDefault,
+ RuntimeContextSource::BootstrapCli,
+ )
+ .expect("macOS bootstrap"),
ServiceId::new("myc").expect("service"),
InstanceId::new("primary").expect("instance"),
)
- .expect("runtime context")
+ .expect("macOS context");
+ assert_eq!(
+ macos.paths().config(),
+ PathBuf::from(
+ "/Users/treesap/Library/Application Support/Radroots/config/services/myc/primary"
+ )
+ );
+ assert_eq!(
+ macos.paths().state(),
+ PathBuf::from(
+ "/Users/treesap/Library/Application Support/Radroots/data/services/myc/primary"
+ )
+ );
+ assert_eq!(
+ macos.paths().cache(),
+ PathBuf::from("/Users/treesap/Library/Caches/Radroots/services/myc/primary")
+ );
+ assert_eq!(
+ macos.paths().logs(),
+ PathBuf::from("/Users/treesap/Library/Logs/Radroots/services/myc/primary")
+ );
+ assert_eq!(
+ macos.paths().run(),
+ PathBuf::from(
+ "/Users/treesap/Library/Application Support/Radroots/run/services/myc/primary"
+ )
+ );
+ assert_eq!(
+ macos.paths().secrets(),
+ PathBuf::from(
+ "/Users/treesap/Library/Application Support/Radroots/secrets/services/myc/primary"
+ )
+ );
+
+ let appdata = PathBuf::from(r"C:\Users\treesap\AppData\Roaming");
+ let localappdata = PathBuf::from(r"C:\Users\treesap\AppData\Local");
+ let windows = RuntimeContext::resolve(
+ &RadrootsPathResolver::new(
+ RadrootsPlatform::Windows,
+ RadrootsHostEnvironment {
+ appdata_dir: Some(appdata.clone()),
+ localappdata_dir: Some(localappdata.clone()),
+ ..RadrootsHostEnvironment::default()
+ },
+ ),
+ RuntimeContextBootstrap::new(
+ RadrootsPathProfile::InteractiveUser,
+ None,
+ RuntimeContextSource::SafeDefault,
+ RuntimeContextSource::BootstrapCli,
+ )
+ .expect("Windows bootstrap"),
+ ServiceId::new("rhi").expect("service"),
+ InstanceId::new("default").expect("instance"),
+ )
+ .expect("Windows context");
+ let suffix = PathBuf::from("services/rhi/default");
+ assert_eq!(
+ windows.paths().config(),
+ appdata.join("Radroots/config").join(&suffix)
+ );
+ assert_eq!(
+ windows.paths().state(),
+ localappdata.join("Radroots/data").join(&suffix)
+ );
+ assert_eq!(
+ windows.paths().cache(),
+ localappdata.join("Radroots/cache").join(&suffix)
+ );
+ assert_eq!(
+ windows.paths().logs(),
+ localappdata.join("Radroots/logs").join(&suffix)
+ );
+ assert_eq!(
+ windows.paths().run(),
+ localappdata.join("Radroots/run").join(&suffix)
+ );
+ assert_eq!(
+ windows.paths().secrets(),
+ appdata.join("Radroots/secrets").join(&suffix)
+ );
+
+ assert_eq!(
+ RuntimeContext::resolve(
+ &RadrootsPathResolver::new(
+ RadrootsPlatform::Windows,
+ RadrootsHostEnvironment::default(),
+ ),
+ RuntimeContextBootstrap::new(
+ RadrootsPathProfile::InteractiveUser,
+ None,
+ RuntimeContextSource::SafeDefault,
+ RuntimeContextSource::BootstrapCli,
+ )
+ .expect("missing-directory bootstrap"),
+ ServiceId::new("myc").expect("service"),
+ InstanceId::new("primary").expect("instance"),
+ ),
+ Err(RuntimeContextError::PathSelection)
+ );
+ }
+
+ #[test]
+ fn retained_linux_xdg_vectors_are_exact_and_ignore_invalid_optional_values() {
+ fn resolve(
+ environment: RadrootsHostEnvironment,
+ ) -> Result<RuntimeContext, RuntimeContextError> {
+ RuntimeContext::resolve(
+ &RadrootsPathResolver::new(RadrootsPlatform::Linux, environment),
+ RuntimeContextBootstrap::new(
+ RadrootsPathProfile::InteractiveUser,
+ None,
+ RuntimeContextSource::SafeDefault,
+ RuntimeContextSource::BootstrapCli,
+ )
+ .expect("Linux bootstrap"),
+ ServiceId::new("myc").expect("service"),
+ InstanceId::new("primary").expect("instance"),
+ )
+ }
+
+ let configured = resolve(RadrootsHostEnvironment {
+ home_dir: Some(PathBuf::from("/home/treesap")),
+ xdg_config_home: Some(PathBuf::from("/xdg/config")),
+ xdg_data_home: Some(PathBuf::from("/xdg/data")),
+ xdg_state_home: Some(PathBuf::from("/xdg/state")),
+ xdg_cache_home: Some(PathBuf::from("/xdg/cache")),
+ xdg_runtime_dir: Some(PathBuf::from("/xdg/run")),
+ ..RadrootsHostEnvironment::default()
+ })
+ .expect("configured XDG context");
+ assert_eq!(
+ configured.paths().config(),
+ PathBuf::from("/xdg/config/radroots/services/myc/primary")
+ );
+ assert_eq!(
+ configured.paths().state(),
+ PathBuf::from("/xdg/data/radroots/services/myc/primary")
+ );
+ assert_eq!(
+ configured.paths().cache(),
+ PathBuf::from("/xdg/cache/radroots/services/myc/primary")
+ );
+ assert_eq!(
+ configured.paths().logs(),
+ PathBuf::from("/xdg/state/radroots/logs/services/myc/primary")
+ );
+ assert_eq!(
+ configured.paths().run(),
+ PathBuf::from("/xdg/run/radroots/services/myc/primary")
+ );
+ assert_eq!(
+ configured.paths().secrets(),
+ PathBuf::from("/xdg/config/radroots/secrets/services/myc/primary")
+ );
+
+ for invalid in ["", "relative"] {
+ let config = resolve(RadrootsHostEnvironment {
+ home_dir: Some(PathBuf::from("/home/treesap")),
+ xdg_config_home: Some(PathBuf::from(invalid)),
+ xdg_runtime_dir: Some(PathBuf::from("/run/user/1000")),
+ ..RadrootsHostEnvironment::default()
+ })
+ .expect("invalid config override is ignored");
+ assert_eq!(
+ config.paths().config(),
+ PathBuf::from("/home/treesap/.config/radroots/services/myc/primary")
+ );
+
+ let data = resolve(RadrootsHostEnvironment {
+ home_dir: Some(PathBuf::from("/home/treesap")),
+ xdg_data_home: Some(PathBuf::from(invalid)),
+ xdg_runtime_dir: Some(PathBuf::from("/run/user/1000")),
+ ..RadrootsHostEnvironment::default()
+ })
+ .expect("invalid data override is ignored");
+ assert_eq!(
+ data.paths().state(),
+ PathBuf::from("/home/treesap/.local/share/radroots/services/myc/primary")
+ );
+
+ let state = resolve(RadrootsHostEnvironment {
+ home_dir: Some(PathBuf::from("/home/treesap")),
+ xdg_state_home: Some(PathBuf::from(invalid)),
+ xdg_runtime_dir: Some(PathBuf::from("/run/user/1000")),
+ ..RadrootsHostEnvironment::default()
+ })
+ .expect("invalid state override is ignored");
+ assert_eq!(
+ state.paths().logs(),
+ PathBuf::from("/home/treesap/.local/state/radroots/logs/services/myc/primary")
+ );
+
+ let cache = resolve(RadrootsHostEnvironment {
+ home_dir: Some(PathBuf::from("/home/treesap")),
+ xdg_cache_home: Some(PathBuf::from(invalid)),
+ xdg_runtime_dir: Some(PathBuf::from("/run/user/1000")),
+ ..RadrootsHostEnvironment::default()
+ })
+ .expect("invalid cache override is ignored");
+ assert_eq!(
+ cache.paths().cache(),
+ PathBuf::from("/home/treesap/.cache/radroots/services/myc/primary")
+ );
+
+ assert_eq!(
+ resolve(RadrootsHostEnvironment {
+ home_dir: Some(PathBuf::from("/home/treesap")),
+ xdg_runtime_dir: Some(PathBuf::from(invalid)),
+ ..RadrootsHostEnvironment::default()
+ }),
+ Err(RuntimeContextError::PathSelection)
+ );
+ }
}
#[test]
diff --git a/crates/runtime_paths/src/conventions.rs b/crates/runtime_paths/src/conventions.rs
@@ -5,19 +5,13 @@ use std::{
use thiserror::Error;
-use crate::{
- InstanceId, RadrootsPathOverrides, RadrootsPathProfile, RadrootsPathResolver,
- RadrootsRuntimeNamespace, RadrootsRuntimePathsError, RadrootsServiceInstanceNamespace,
- RadrootsServiceInstancePaths, ServiceId,
-};
+use crate::{RadrootsRuntimePathsError, RadrootsServiceInstancePaths};
pub const DEFAULT_CONFIG_FILE_NAME: &str = "config.toml";
pub const SERVICE_STATE_DATABASE_FILE_NAME: &str = "state.sqlite";
pub const SERVICE_STATE_LOCK_FILE_NAME: &str = "state.lock";
pub const SERVICE_ADMIN_SOCKET_FILE_NAME: &str = "admin.sock";
pub const SERVICE_CREDENTIAL_ARTIFACT_NAME_MAX_BYTES: usize = 128;
-pub const DEFAULT_SERVICE_IDENTITY_FILE_NAME: &str = "identity.secret.json";
-pub const DEFAULT_SHARED_IDENTITY_FILE_NAME: &str = "default.json";
pub const DEFAULT_SHARED_GEONAMES_NAMESPACE_KIND: &str = "shared";
pub const DEFAULT_SHARED_GEONAMES_NAMESPACE_VALUE: &str = "geonames";
pub const DEFAULT_SHARED_GEONAMES_NAMESPACE: &str = "shared/geonames";
@@ -26,13 +20,6 @@ pub const DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE_VALUE: &str = "runtime_store";
pub const DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE: &str = "shared/runtime_store";
pub const DEFAULT_SHARED_RUNTIME_STORE_DB_FILE_NAME: &str = "runtime_store.sqlite";
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct RadrootsBootstrapPaths {
- pub config_path: PathBuf,
- pub logs_dir: PathBuf,
- pub identity_path: PathBuf,
-}
-
/// A validated service-owned credential artifact filename.
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct ServiceCredentialArtifactName(String);
@@ -168,55 +155,6 @@ pub fn service_credential_artifact_path(
paths.secrets().join(name.as_str())
}
-pub fn default_service_instance_paths(
- resolver: &RadrootsPathResolver,
- profile: RadrootsPathProfile,
- overrides: &RadrootsPathOverrides,
- service_id: &ServiceId,
- instance_id: &InstanceId,
-) -> Result<RadrootsServiceInstancePaths, RadrootsRuntimePathsError> {
- let namespace = RadrootsServiceInstanceNamespace::new(service_id.clone(), instance_id.clone());
- let roots = resolver.resolve(profile, overrides)?;
- Ok(RadrootsServiceInstancePaths::from_resolved_roots(
- &roots, &namespace,
- ))
-}
-
-pub fn default_namespaced_bootstrap_paths(
- resolver: &RadrootsPathResolver,
- profile: RadrootsPathProfile,
- overrides: &RadrootsPathOverrides,
- namespace: &RadrootsRuntimeNamespace,
- identity_file_name: &str,
-) -> Result<RadrootsBootstrapPaths, RadrootsRuntimePathsError> {
- let namespaced = resolver.resolve(profile, overrides)?.namespaced(namespace);
- Ok(RadrootsBootstrapPaths {
- config_path: namespaced.config.join(DEFAULT_CONFIG_FILE_NAME),
- logs_dir: namespaced.logs,
- identity_path: namespaced.secrets.join(identity_file_name),
- })
-}
-
-pub fn default_shared_identity_path(
- resolver: &RadrootsPathResolver,
- profile: RadrootsPathProfile,
- overrides: &RadrootsPathOverrides,
-) -> Result<PathBuf, RadrootsRuntimePathsError> {
- let namespace = RadrootsRuntimeNamespace::shared("identities")?;
- let namespaced = resolver.resolve(profile, overrides)?.namespaced(&namespace);
- Ok(namespaced.secrets.join(DEFAULT_SHARED_IDENTITY_FILE_NAME))
-}
-
-pub fn default_shared_runtime_logs_dir(
- resolver: &RadrootsPathResolver,
- profile: RadrootsPathProfile,
- overrides: &RadrootsPathOverrides,
-) -> Result<PathBuf, RadrootsRuntimePathsError> {
- let namespace = RadrootsRuntimeNamespace::shared("runtime")?;
- let namespaced = resolver.resolve(profile, overrides)?.namespaced(&namespace);
- Ok(namespaced.logs)
-}
-
#[must_use]
pub fn default_shared_runtime_store_root_from_data_root(data_root: impl AsRef<Path>) -> PathBuf {
data_root
@@ -278,111 +216,41 @@ pub fn default_shared_runtime_store_database_path_from_shared_accounts_data_root
mod tests {
use std::path::PathBuf;
- use crate::{
- RadrootsHostEnvironment, RadrootsPlatform, RadrootsRuntimeNamespace,
- RadrootsRuntimePathsError,
- };
-
use super::{
- DEFAULT_CONFIG_FILE_NAME, DEFAULT_SERVICE_IDENTITY_FILE_NAME,
- DEFAULT_SHARED_GEONAMES_NAMESPACE, DEFAULT_SHARED_IDENTITY_FILE_NAME,
+ DEFAULT_CONFIG_FILE_NAME, DEFAULT_SHARED_GEONAMES_NAMESPACE,
DEFAULT_SHARED_RUNTIME_STORE_DB_FILE_NAME, DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE,
SERVICE_ADMIN_SOCKET_FILE_NAME, SERVICE_CREDENTIAL_ARTIFACT_NAME_MAX_BYTES,
SERVICE_STATE_DATABASE_FILE_NAME, SERVICE_STATE_LOCK_FILE_NAME,
ServiceCredentialArtifactName, ServiceCredentialArtifactNameError,
- default_namespaced_bootstrap_paths, default_service_instance_artifacts,
- default_service_instance_paths, default_shared_geonames_database_file_name,
+ default_service_instance_artifacts, default_shared_geonames_database_file_name,
default_shared_geonames_database_path_from_cache_root,
- default_shared_geonames_root_from_cache_root, default_shared_identity_path,
- default_shared_runtime_logs_dir, default_shared_runtime_store_database_path_from_data_root,
+ default_shared_geonames_root_from_cache_root,
+ default_shared_runtime_store_database_path_from_data_root,
default_shared_runtime_store_database_path_from_shared_accounts_data_root,
default_shared_runtime_store_root_from_data_root,
default_shared_runtime_store_root_from_shared_accounts_data_root,
service_credential_artifact_path,
};
- use crate::{InstanceId, ServiceId};
-
- #[test]
- fn service_instance_paths_are_exact_for_linux_and_xdg_profiles() {
- let service_id = ServiceId::new("myc").expect("service id");
- let instance_id = InstanceId::new("primary").expect("instance id");
- let service_host = crate::RadrootsPathResolver::new(
- RadrootsPlatform::Linux,
- RadrootsHostEnvironment::default(),
- );
- let service_paths = default_service_instance_paths(
- &service_host,
- crate::RadrootsPathProfile::ServiceHost,
- &crate::RadrootsPathOverrides::default(),
- &service_id,
- &instance_id,
- )
- .expect("service-host paths");
- assert_eq!(
- service_paths.config(),
- PathBuf::from("/etc/radroots/services/myc/primary")
- );
- assert_eq!(
- service_paths.state(),
- PathBuf::from("/var/lib/radroots/services/myc/primary")
- );
- assert_eq!(
- service_paths.cache(),
- PathBuf::from("/var/cache/radroots/services/myc/primary")
- );
- assert_eq!(
- service_paths.logs(),
- PathBuf::from("/var/log/radroots/services/myc/primary")
- );
- assert_eq!(
- service_paths.run(),
- PathBuf::from("/run/radroots/services/myc/primary")
- );
- assert_eq!(
- service_paths.secrets(),
- PathBuf::from("/etc/radroots/secrets/services/myc/primary")
- );
+ use crate::{
+ InstanceId, RadrootsHostEnvironment, RadrootsPathProfile, RadrootsPathResolver,
+ RadrootsPlatform, RadrootsRuntimePathsError, RuntimeContext, RuntimeContextBootstrap,
+ RuntimeContextSource, ServiceId,
+ };
- let interactive = crate::RadrootsPathResolver::new(
- RadrootsPlatform::Linux,
- RadrootsHostEnvironment {
- home_dir: Some(PathBuf::from("/home/treesap")),
- xdg_runtime_dir: Some(PathBuf::from("/run/user/1000")),
- ..RadrootsHostEnvironment::default()
- },
- );
- let interactive_paths = default_service_instance_paths(
- &interactive,
- crate::RadrootsPathProfile::InteractiveUser,
- &crate::RadrootsPathOverrides::default(),
- &service_id,
- &instance_id,
+ fn service_context(service: &str, instance: &str) -> RuntimeContext {
+ RuntimeContext::resolve(
+ &RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default()),
+ RuntimeContextBootstrap::new(
+ RadrootsPathProfile::ServiceHost,
+ None,
+ RuntimeContextSource::SafeDefault,
+ RuntimeContextSource::BootstrapCli,
+ )
+ .expect("bootstrap"),
+ ServiceId::new(service).expect("service"),
+ InstanceId::new(instance).expect("instance"),
)
- .expect("XDG paths");
- assert_eq!(
- interactive_paths.config(),
- PathBuf::from("/home/treesap/.config/radroots/services/myc/primary")
- );
- assert_eq!(
- interactive_paths.state(),
- PathBuf::from("/home/treesap/.local/share/radroots/services/myc/primary")
- );
- assert_eq!(
- interactive_paths.cache(),
- PathBuf::from("/home/treesap/.cache/radroots/services/myc/primary")
- );
- assert_eq!(
- interactive_paths.logs(),
- PathBuf::from("/home/treesap/.local/state/radroots/logs/services/myc/primary")
- );
- assert_eq!(
- interactive_paths.run(),
- PathBuf::from("/run/user/1000/radroots/services/myc/primary")
- );
- assert_eq!(
- interactive_paths.secrets(),
- PathBuf::from("/home/treesap/.config/radroots/secrets/services/myc/primary")
- );
+ .expect("context")
}
#[test]
@@ -392,19 +260,8 @@ mod tests {
assert_eq!(SERVICE_STATE_LOCK_FILE_NAME, "state.lock");
assert_eq!(SERVICE_ADMIN_SOCKET_FILE_NAME, "admin.sock");
- let resolver = crate::RadrootsPathResolver::new(
- RadrootsPlatform::Linux,
- RadrootsHostEnvironment::default(),
- );
- let paths = default_service_instance_paths(
- &resolver,
- crate::RadrootsPathProfile::ServiceHost,
- &crate::RadrootsPathOverrides::default(),
- &ServiceId::new("myc").expect("service id"),
- &InstanceId::new("primary").expect("instance id"),
- )
- .expect("instance paths");
- let artifacts = default_service_instance_artifacts(&paths);
+ let context = service_context("myc", "primary");
+ let artifacts = default_service_instance_artifacts(context.paths());
assert_eq!(
artifacts.config(),
@@ -426,18 +283,8 @@ mod tests {
#[test]
fn credential_artifact_names_are_validated_and_remain_outside_state() {
- let resolver = crate::RadrootsPathResolver::new(
- RadrootsPlatform::Linux,
- RadrootsHostEnvironment::default(),
- );
- let paths = default_service_instance_paths(
- &resolver,
- crate::RadrootsPathProfile::ServiceHost,
- &crate::RadrootsPathOverrides::default(),
- &ServiceId::new("rhi").expect("service id"),
- &InstanceId::new("default").expect("instance id"),
- )
- .expect("instance paths");
+ let context = service_context("rhi", "default");
+ let paths = context.paths();
let name =
ServiceCredentialArtifactName::new("identity.secret.json").expect("credential name");
assert_eq!(
@@ -445,14 +292,14 @@ mod tests {
"ServiceCredentialArtifactName([redacted])"
);
assert!(!format!("{name:?}").contains("identity.secret.json"));
- let credential = service_credential_artifact_path(&paths, &name);
+ let credential = service_credential_artifact_path(paths, &name);
assert_eq!(
credential,
PathBuf::from("/etc/radroots/secrets/services/rhi/default/identity.secret.json")
);
assert!(!credential.starts_with(paths.state()));
- let artifacts = default_service_instance_artifacts(&paths);
+ let artifacts = default_service_instance_artifacts(paths);
let artifacts_debug = format!("{artifacts:?}");
assert_eq!(
artifacts_debug,
@@ -501,83 +348,8 @@ mod tests {
}
#[test]
- fn namespaced_bootstrap_paths_use_canonical_interactive_roots() {
- let resolver = crate::RadrootsPathResolver::new(
- RadrootsPlatform::Linux,
- RadrootsHostEnvironment {
- home_dir: Some(PathBuf::from("/home/treesap")),
- xdg_runtime_dir: Some(PathBuf::from("/run/user/1000")),
- ..RadrootsHostEnvironment::default()
- },
- );
- let namespace =
- RadrootsRuntimeNamespace::service("radrootsd").expect("service namespace should parse");
-
- let paths = default_namespaced_bootstrap_paths(
- &resolver,
- crate::RadrootsPathProfile::InteractiveUser,
- &crate::RadrootsPathOverrides::default(),
- &namespace,
- DEFAULT_SERVICE_IDENTITY_FILE_NAME,
- )
- .expect("service bootstrap paths should resolve");
-
- assert_eq!(
- paths.config_path,
- PathBuf::from("/home/treesap/.config/radroots/services/radrootsd/config.toml")
- );
- assert_eq!(
- paths.logs_dir,
- PathBuf::from("/home/treesap/.local/state/radroots/logs/services/radrootsd")
- );
- assert_eq!(
- paths.identity_path,
- PathBuf::from(
- "/home/treesap/.config/radroots/secrets/services/radrootsd/identity.secret.json"
- )
- );
- }
-
- #[test]
- fn shared_defaults_use_shared_namespaces() {
- let resolver = crate::RadrootsPathResolver::new(
- RadrootsPlatform::Macos,
- RadrootsHostEnvironment {
- home_dir: Some(PathBuf::from("/Users/treesap")),
- ..RadrootsHostEnvironment::default()
- },
- );
-
- let identity_path = default_shared_identity_path(
- &resolver,
- crate::RadrootsPathProfile::InteractiveUser,
- &crate::RadrootsPathOverrides::default(),
- )
- .expect("shared identity path should resolve");
- assert_eq!(
- identity_path,
- PathBuf::from(
- "/Users/treesap/Library/Application Support/Radroots/secrets/shared/identities"
- )
- .join(DEFAULT_SHARED_IDENTITY_FILE_NAME)
- );
-
- let logs_dir = default_shared_runtime_logs_dir(
- &resolver,
- crate::RadrootsPathProfile::InteractiveUser,
- &crate::RadrootsPathOverrides::default(),
- )
- .expect("shared runtime logs dir should resolve");
- assert_eq!(
- logs_dir,
- PathBuf::from("/Users/treesap/Library/Logs/Radroots/shared/runtime")
- );
- }
-
- #[test]
fn shared_runtime_store_paths_use_canonical_shared_namespace() {
let data_root = PathBuf::from("/repo/infra/local/runtime/radroots/data");
-
assert_eq!(
default_shared_runtime_store_root_from_data_root(&data_root),
data_root.join(DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE)
@@ -593,7 +365,6 @@ mod tests {
#[test]
fn shared_geonames_paths_use_canonical_shared_cache_namespace() {
let cache_root = PathBuf::from("/repo/infra/local/runtime/radroots/cache");
-
assert_eq!(
default_shared_geonames_root_from_cache_root(&cache_root),
cache_root.join(DEFAULT_SHARED_GEONAMES_NAMESPACE)
@@ -614,7 +385,6 @@ mod tests {
fn shared_runtime_store_paths_derive_from_shared_accounts_data_root() {
let shared_accounts_data_root =
PathBuf::from("/repo/infra/local/runtime/radroots/data/shared/accounts");
-
assert_eq!(
default_shared_runtime_store_root_from_shared_accounts_data_root(
&shared_accounts_data_root
@@ -623,13 +393,6 @@ mod tests {
PathBuf::from("/repo/infra/local/runtime/radroots/data/shared/runtime_store")
);
assert_eq!(
- default_shared_runtime_store_root_from_shared_accounts_data_root(
- shared_accounts_data_root.clone()
- )
- .expect("shared runtime-store root from owned path"),
- PathBuf::from("/repo/infra/local/runtime/radroots/data/shared/runtime_store")
- );
- assert_eq!(
default_shared_runtime_store_database_path_from_shared_accounts_data_root(
&shared_accounts_data_root
)
@@ -639,72 +402,12 @@ mod tests {
)
);
- let err =
- default_shared_runtime_store_root_from_shared_accounts_data_root(PathBuf::from("/"))
- .expect_err("root path has no parent shared data root");
assert_eq!(
- err,
+ default_shared_runtime_store_root_from_shared_accounts_data_root(PathBuf::from("/"))
+ .expect_err("root path has no parent"),
RadrootsRuntimePathsError::SharedAccountsDataRootMissingParent {
path: PathBuf::from("/")
}
);
}
-
- #[test]
- fn namespaced_bootstrap_paths_propagate_resolver_errors() {
- let resolver =
- crate::RadrootsPathResolver::new(RadrootsPlatform::Linux, Default::default());
- let namespace =
- RadrootsRuntimeNamespace::service("radrootsd").expect("service namespace should parse");
-
- let err = default_namespaced_bootstrap_paths(
- &resolver,
- crate::RadrootsPathProfile::InteractiveUser,
- &crate::RadrootsPathOverrides::default(),
- &namespace,
- DEFAULT_SERVICE_IDENTITY_FILE_NAME,
- )
- .expect_err("interactive user should require a home dir");
-
- assert_eq!(
- err,
- crate::RadrootsRuntimePathsError::MissingHomeDir {
- platform: RadrootsPlatform::Linux,
- }
- );
- }
-
- #[test]
- fn shared_defaults_propagate_profile_errors() {
- let resolver =
- crate::RadrootsPathResolver::new(RadrootsPlatform::Android, Default::default());
-
- let identity_err = default_shared_identity_path(
- &resolver,
- crate::RadrootsPathProfile::InteractiveUser,
- &crate::RadrootsPathOverrides::default(),
- )
- .expect_err("interactive_user should be unsupported on android");
- assert_eq!(
- identity_err,
- crate::RadrootsRuntimePathsError::UnsupportedProfilePlatform {
- profile: crate::RadrootsPathProfile::InteractiveUser,
- platform: RadrootsPlatform::Android,
- }
- );
-
- let logs_err = default_shared_runtime_logs_dir(
- &resolver,
- crate::RadrootsPathProfile::ServiceHost,
- &crate::RadrootsPathOverrides::default(),
- )
- .expect_err("service_host should be unsupported on android");
- assert_eq!(
- logs_err,
- crate::RadrootsRuntimePathsError::UnsupportedProfilePlatform {
- profile: crate::RadrootsPathProfile::ServiceHost,
- platform: RadrootsPlatform::Android,
- }
- );
- }
}
diff --git a/crates/runtime_paths/src/error.rs b/crates/runtime_paths/src/error.rs
@@ -24,18 +24,12 @@ pub enum RadrootsRuntimePathsError {
#[error("repo_local base root must be an absolute non-root path without parent traversal")]
InvalidRepoLocalRoot,
- #[error("mobile_native requires explicit logical roots")]
- MissingMobileRoots,
-
#[error("{profile} is not supported on {platform}")]
UnsupportedProfilePlatform {
profile: RadrootsPathProfile,
platform: RadrootsPlatform,
},
- #[error("runtime namespace `{value}` must be one non-empty path component")]
- InvalidNamespaceComponent { value: String },
-
#[error("shared accounts data root `{path:?}` has no parent shared data root")]
SharedAccountsDataRootMissingParent { path: PathBuf },
}
diff --git a/crates/runtime_paths/src/lib.rs b/crates/runtime_paths/src/lib.rs
@@ -4,7 +4,6 @@ pub mod context;
pub mod conventions;
pub mod error;
pub mod identifier;
-pub mod namespace;
pub mod platform;
pub mod roots;
pub mod service;
@@ -14,20 +13,18 @@ pub use context::{
RuntimeContextSources,
};
pub use conventions::{
- DEFAULT_CONFIG_FILE_NAME, DEFAULT_SERVICE_IDENTITY_FILE_NAME,
- DEFAULT_SHARED_GEONAMES_NAMESPACE, DEFAULT_SHARED_GEONAMES_NAMESPACE_KIND,
- DEFAULT_SHARED_GEONAMES_NAMESPACE_VALUE, DEFAULT_SHARED_IDENTITY_FILE_NAME,
+ DEFAULT_CONFIG_FILE_NAME, DEFAULT_SHARED_GEONAMES_NAMESPACE,
+ DEFAULT_SHARED_GEONAMES_NAMESPACE_KIND, DEFAULT_SHARED_GEONAMES_NAMESPACE_VALUE,
DEFAULT_SHARED_RUNTIME_STORE_DB_FILE_NAME, DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE,
DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE_KIND, DEFAULT_SHARED_RUNTIME_STORE_NAMESPACE_VALUE,
- RadrootsBootstrapPaths, RadrootsServiceInstanceArtifacts, SERVICE_ADMIN_SOCKET_FILE_NAME,
+ RadrootsServiceInstanceArtifacts, SERVICE_ADMIN_SOCKET_FILE_NAME,
SERVICE_CREDENTIAL_ARTIFACT_NAME_MAX_BYTES, SERVICE_STATE_DATABASE_FILE_NAME,
SERVICE_STATE_LOCK_FILE_NAME, ServiceCredentialArtifactName,
- ServiceCredentialArtifactNameError, default_namespaced_bootstrap_paths,
- default_service_instance_artifacts, default_service_instance_paths,
+ ServiceCredentialArtifactNameError, default_service_instance_artifacts,
default_shared_geonames_database_file_name,
default_shared_geonames_database_path_from_cache_root,
- default_shared_geonames_root_from_cache_root, default_shared_identity_path,
- default_shared_runtime_logs_dir, default_shared_runtime_store_database_path_from_data_root,
+ default_shared_geonames_root_from_cache_root,
+ default_shared_runtime_store_database_path_from_data_root,
default_shared_runtime_store_database_path_from_shared_accounts_data_root,
default_shared_runtime_store_root_from_data_root,
default_shared_runtime_store_root_from_shared_accounts_data_root,
@@ -38,327 +35,6 @@ pub use identifier::{
INSTANCE_ID_MAX_BYTES, InstanceId, SERVICE_ID_MAX_BYTES, ServiceId, ServiceIdentityError,
ServiceIdentityKind,
};
-pub use namespace::{
- RadrootsRuntimeNamespace, RadrootsRuntimeNamespaceKind, RadrootsServiceInstanceNamespace,
-};
pub use platform::{RadrootsHostEnvironment, RadrootsPathProfile, RadrootsPlatform};
-pub use roots::{RadrootsPathOverrides, RadrootsPathResolver, RadrootsPaths};
-pub use service::{
- RadrootsRuntimePathConfigEntry, RadrootsRuntimePathPolicyContract,
- RadrootsRuntimePathSelection, RadrootsRuntimePathSelectionError,
- RadrootsRuntimeSelectionContract, RadrootsRuntimeSelectionOverrideContract,
- RadrootsServiceInstancePaths,
-};
-
-#[cfg(test)]
-mod tests {
- use std::path::PathBuf;
-
- use super::{
- RadrootsHostEnvironment, RadrootsPathOverrides, RadrootsPathProfile, RadrootsPathResolver,
- RadrootsPaths, RadrootsPlatform, RadrootsRuntimeNamespace, RadrootsRuntimePathsError,
- };
-
- #[test]
- fn interactive_user_linux_uses_xdg_defaults_and_explicit_runtime() {
- let resolver = RadrootsPathResolver::new(
- RadrootsPlatform::Linux,
- RadrootsHostEnvironment {
- home_dir: Some(PathBuf::from("/home/treesap")),
- xdg_runtime_dir: Some(PathBuf::from("/run/user/1000")),
- ..RadrootsHostEnvironment::default()
- },
- );
-
- let roots = resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect("resolve linux interactive roots");
-
- assert_eq!(
- roots.config,
- PathBuf::from("/home/treesap/.config/radroots")
- );
- assert_eq!(
- roots.data,
- PathBuf::from("/home/treesap/.local/share/radroots")
- );
- assert_eq!(
- roots.logs,
- PathBuf::from("/home/treesap/.local/state/radroots/logs")
- );
- assert_eq!(roots.run, PathBuf::from("/run/user/1000/radroots"));
- assert_eq!(
- roots.secrets,
- PathBuf::from("/home/treesap/.config/radroots/secrets")
- );
- }
-
- #[test]
- fn interactive_user_macos_uses_native_library_roots() {
- let resolver = RadrootsPathResolver::new(
- RadrootsPlatform::Macos,
- RadrootsHostEnvironment {
- home_dir: Some(PathBuf::from("/Users/treesap")),
- ..RadrootsHostEnvironment::default()
- },
- );
-
- let roots = resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect("resolve macos interactive roots");
-
- assert_eq!(
- roots,
- RadrootsPaths {
- config: PathBuf::from("/Users/treesap/Library/Application Support/Radroots/config",),
- data: PathBuf::from("/Users/treesap/Library/Application Support/Radroots/data",),
- cache: PathBuf::from("/Users/treesap/Library/Caches/Radroots"),
- logs: PathBuf::from("/Users/treesap/Library/Logs/Radroots"),
- run: PathBuf::from("/Users/treesap/Library/Application Support/Radroots/run",),
- secrets: PathBuf::from(
- "/Users/treesap/Library/Application Support/Radroots/secrets",
- ),
- }
- );
- }
-
- #[test]
- fn interactive_user_windows_uses_native_user_roots() {
- let resolver = RadrootsPathResolver::new(
- RadrootsPlatform::Windows,
- RadrootsHostEnvironment {
- appdata_dir: Some(PathBuf::from(r"C:\Users\treesap\AppData\Roaming")),
- localappdata_dir: Some(PathBuf::from(r"C:\Users\treesap\AppData\Local")),
- ..RadrootsHostEnvironment::default()
- },
- );
-
- let roots = resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect("resolve windows interactive roots");
-
- assert_eq!(
- roots,
- RadrootsPaths {
- config: PathBuf::from(r"C:\Users\treesap\AppData\Roaming")
- .join("Radroots")
- .join("config"),
- data: PathBuf::from(r"C:\Users\treesap\AppData\Local")
- .join("Radroots")
- .join("data"),
- cache: PathBuf::from(r"C:\Users\treesap\AppData\Local")
- .join("Radroots")
- .join("cache"),
- logs: PathBuf::from(r"C:\Users\treesap\AppData\Local")
- .join("Radroots")
- .join("logs"),
- run: PathBuf::from(r"C:\Users\treesap\AppData\Local")
- .join("Radroots")
- .join("run"),
- secrets: PathBuf::from(r"C:\Users\treesap\AppData\Roaming")
- .join("Radroots")
- .join("secrets"),
- }
- );
- }
-
- #[test]
- fn service_host_linux_uses_canonical_service_roots() {
- let resolver =
- RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default());
-
- let roots = resolver
- .resolve(
- RadrootsPathProfile::ServiceHost,
- &RadrootsPathOverrides::default(),
- )
- .expect("resolve service_host roots");
-
- assert_eq!(
- roots,
- RadrootsPaths {
- config: PathBuf::from("/etc/radroots"),
- data: PathBuf::from("/var/lib/radroots"),
- cache: PathBuf::from("/var/cache/radroots"),
- logs: PathBuf::from("/var/log/radroots"),
- run: PathBuf::from("/run/radroots"),
- secrets: PathBuf::from("/etc/radroots/secrets"),
- }
- );
- }
-
- #[test]
- fn service_host_is_unsupported_outside_linux() {
- for platform in [
- RadrootsPlatform::Macos,
- RadrootsPlatform::Windows,
- RadrootsPlatform::Android,
- RadrootsPlatform::Ios,
- RadrootsPlatform::Other,
- ] {
- let resolver = RadrootsPathResolver::new(platform, RadrootsHostEnvironment::default());
- assert_eq!(
- resolver
- .resolve(
- RadrootsPathProfile::ServiceHost,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("service_host must be unsupported outside linux"),
- RadrootsRuntimePathsError::UnsupportedProfilePlatform {
- profile: RadrootsPathProfile::ServiceHost,
- platform,
- }
- );
- }
- }
-
- #[test]
- fn repo_local_requires_explicit_base_root() {
- let resolver =
- RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default());
-
- let err = resolver
- .resolve(
- RadrootsPathProfile::RepoLocal,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("repo_local should require an explicit base root");
-
- assert_eq!(err, RadrootsRuntimePathsError::MissingRepoLocalRoot);
- }
-
- #[test]
- fn repo_local_uses_explicit_base_root() {
- let resolver =
- RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default());
-
- let roots = resolver
- .resolve(
- RadrootsPathProfile::RepoLocal,
- &RadrootsPathOverrides::repo_local("/repo/.local/radroots"),
- )
- .expect("resolve repo_local roots");
-
- assert_eq!(
- roots,
- RadrootsPaths::from_base_root("/repo/.local/radroots")
- );
- }
-
- #[test]
- fn mobile_native_requires_explicit_roots() {
- let resolver = RadrootsPathResolver::new(
- RadrootsPlatform::Android,
- RadrootsHostEnvironment::default(),
- );
-
- let err = resolver
- .resolve(
- RadrootsPathProfile::MobileNative,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("mobile_native should require explicit roots");
-
- assert_eq!(err, RadrootsRuntimePathsError::MissingMobileRoots);
- }
-
- #[test]
- fn mobile_native_returns_explicit_roots() {
- let resolver =
- RadrootsPathResolver::new(RadrootsPlatform::Ios, RadrootsHostEnvironment::default());
- let mobile_roots = RadrootsPaths {
- config: PathBuf::from("/sandbox/config"),
- data: PathBuf::from("/sandbox/data"),
- cache: PathBuf::from("/sandbox/cache"),
- logs: PathBuf::from("/sandbox/logs"),
- run: PathBuf::from("/sandbox/run"),
- secrets: PathBuf::from("/sandbox/secrets"),
- };
-
- let roots = resolver
- .resolve(
- RadrootsPathProfile::MobileNative,
- &RadrootsPathOverrides::mobile(mobile_roots.clone()),
- )
- .expect("resolve mobile_native roots");
-
- assert_eq!(roots, mobile_roots);
- }
-
- #[test]
- fn namespace_derivation_keeps_runtime_segments_explicit() {
- let namespace = RadrootsRuntimeNamespace::service("myc").expect("namespace");
- let roots = RadrootsPaths::from_base_root("/logical-root");
- let namespaced = roots.namespaced(&namespace);
-
- assert_eq!(
- namespaced.config,
- PathBuf::from("/logical-root/config/services/myc")
- );
- assert_eq!(
- namespaced.data,
- PathBuf::from("/logical-root/data/services/myc")
- );
- assert_eq!(
- namespaced.secrets,
- PathBuf::from("/logical-root/secrets/services/myc")
- );
- }
-
- #[test]
- fn namespace_validation_rejects_path_escape_values() {
- let err = RadrootsRuntimeNamespace::app("../cli").expect_err("invalid namespace");
- assert_eq!(
- err,
- RadrootsRuntimePathsError::InvalidNamespaceComponent {
- value: "../cli".to_owned(),
- }
- );
- }
-
- #[test]
- fn interactive_user_linux_requires_home_for_xdg_defaults() {
- let resolver =
- RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default());
-
- let err = resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("interactive_user on linux should require a home dir");
-
- assert_eq!(
- err,
- RadrootsRuntimePathsError::MissingHomeDir {
- platform: RadrootsPlatform::Linux,
- }
- );
- }
-
- #[test]
- fn interactive_user_windows_requires_native_dirs() {
- let resolver = RadrootsPathResolver::new(
- RadrootsPlatform::Windows,
- RadrootsHostEnvironment::default(),
- );
-
- let err = resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("interactive_user on windows should require native dirs");
-
- assert_eq!(err, RadrootsRuntimePathsError::MissingWindowsUserDirs);
- }
-}
+pub use roots::RadrootsPathResolver;
+pub use service::RadrootsServiceInstancePaths;
diff --git a/crates/runtime_paths/src/namespace.rs b/crates/runtime_paths/src/namespace.rs
@@ -1,236 +0,0 @@
-use std::path::PathBuf;
-
-use crate::{InstanceId, RadrootsRuntimePathsError, ServiceId, ServiceIdentityError};
-
-/// A validated canonical `services/<service>/<instance>` namespace.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct RadrootsServiceInstanceNamespace {
- service_id: ServiceId,
- instance_id: InstanceId,
-}
-
-impl RadrootsServiceInstanceNamespace {
- /// Constructs a namespace from already validated identities.
- #[must_use]
- pub fn new(service_id: ServiceId, instance_id: InstanceId) -> Self {
- Self {
- service_id,
- instance_id,
- }
- }
-
- /// Parses both canonical path components before constructing a namespace.
- pub fn parse(
- service_id: impl Into<String>,
- instance_id: impl Into<String>,
- ) -> Result<Self, ServiceIdentityError> {
- Ok(Self::new(
- ServiceId::new(service_id)?,
- InstanceId::new(instance_id)?,
- ))
- }
-
- /// Returns the validated service identity.
- #[must_use]
- pub fn service_id(&self) -> &ServiceId {
- &self.service_id
- }
-
- /// Returns the validated instance identity.
- #[must_use]
- pub fn instance_id(&self) -> &InstanceId {
- &self.instance_id
- }
-
- /// Returns the canonical relative namespace path.
- #[must_use]
- pub fn relative_path(&self) -> PathBuf {
- PathBuf::from(RadrootsRuntimeNamespaceKind::Service.path_segment())
- .join(self.service_id.as_str())
- .join(self.instance_id.as_str())
- }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum RadrootsRuntimeNamespaceKind {
- App,
- Service,
- Worker,
- Shared,
-}
-
-impl RadrootsRuntimeNamespaceKind {
- #[must_use]
- pub fn path_segment(self) -> &'static str {
- match self {
- Self::App => "apps",
- Self::Service => "services",
- Self::Worker => "workers",
- Self::Shared => "shared",
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct RadrootsRuntimeNamespace {
- kind: RadrootsRuntimeNamespaceKind,
- value: String,
-}
-
-impl RadrootsRuntimeNamespace {
- pub fn app(value: impl Into<String>) -> Result<Self, RadrootsRuntimePathsError> {
- Self::new(RadrootsRuntimeNamespaceKind::App, value)
- }
-
- pub fn service(value: impl Into<String>) -> Result<Self, RadrootsRuntimePathsError> {
- Self::new(RadrootsRuntimeNamespaceKind::Service, value)
- }
-
- pub fn worker(value: impl Into<String>) -> Result<Self, RadrootsRuntimePathsError> {
- Self::new(RadrootsRuntimeNamespaceKind::Worker, value)
- }
-
- pub fn shared(value: impl Into<String>) -> Result<Self, RadrootsRuntimePathsError> {
- Self::new(RadrootsRuntimeNamespaceKind::Shared, value)
- }
-
- pub fn new(
- kind: RadrootsRuntimeNamespaceKind,
- value: impl Into<String>,
- ) -> Result<Self, RadrootsRuntimePathsError> {
- let value = value.into();
- validate_component(&value)?;
- Ok(Self { kind, value })
- }
-
- #[must_use]
- pub fn kind(&self) -> RadrootsRuntimeNamespaceKind {
- self.kind
- }
-
- #[must_use]
- pub fn value(&self) -> &str {
- self.value.as_str()
- }
-
- #[must_use]
- pub fn relative_path(&self) -> PathBuf {
- PathBuf::from(self.kind.path_segment()).join(self.value.as_str())
- }
-}
-
-fn validate_component(value: &str) -> Result<(), RadrootsRuntimePathsError> {
- let trimmed = value.trim();
- if trimmed.is_empty()
- || trimmed == "."
- || trimmed == ".."
- || trimmed.contains('/')
- || trimmed.contains('\\')
- {
- return Err(RadrootsRuntimePathsError::InvalidNamespaceComponent {
- value: value.to_owned(),
- });
- }
- Ok(())
-}
-
-#[cfg(test)]
-mod tests {
- use std::path::PathBuf;
-
- use super::{
- RadrootsRuntimeNamespace, RadrootsRuntimeNamespaceKind, RadrootsServiceInstanceNamespace,
- };
- use crate::{
- InstanceId, RadrootsRuntimePathsError, ServiceId, ServiceIdentityError, ServiceIdentityKind,
- };
-
- #[test]
- fn namespace_kind_path_segments_are_canonical() {
- assert_eq!(RadrootsRuntimeNamespaceKind::App.path_segment(), "apps");
- assert_eq!(
- RadrootsRuntimeNamespaceKind::Service.path_segment(),
- "services"
- );
- assert_eq!(
- RadrootsRuntimeNamespaceKind::Worker.path_segment(),
- "workers"
- );
- assert_eq!(
- RadrootsRuntimeNamespaceKind::Shared.path_segment(),
- "shared"
- );
- }
-
- #[test]
- fn namespace_constructors_preserve_kind_and_value() {
- let app = RadrootsRuntimeNamespace::app("cli").expect("app namespace");
- assert_eq!(app.kind(), RadrootsRuntimeNamespaceKind::App);
- assert_eq!(app.value(), "cli");
- assert_eq!(app.relative_path(), PathBuf::from("apps/cli"));
-
- let service = RadrootsRuntimeNamespace::service("myc").expect("service namespace");
- assert_eq!(service.kind(), RadrootsRuntimeNamespaceKind::Service);
- assert_eq!(service.value(), "myc");
- assert_eq!(service.relative_path(), PathBuf::from("services/myc"));
-
- let worker = RadrootsRuntimeNamespace::worker("rhi").expect("worker namespace");
- assert_eq!(worker.kind(), RadrootsRuntimeNamespaceKind::Worker);
- assert_eq!(worker.value(), "rhi");
- assert_eq!(worker.relative_path(), PathBuf::from("workers/rhi"));
-
- let shared = RadrootsRuntimeNamespace::shared("runtime").expect("shared namespace");
- assert_eq!(shared.kind(), RadrootsRuntimeNamespaceKind::Shared);
- assert_eq!(shared.value(), "runtime");
- assert_eq!(shared.relative_path(), PathBuf::from("shared/runtime"));
- }
-
- #[test]
- fn namespace_validation_rejects_invalid_components() {
- for invalid in ["", " ", ".", "..", "a/b", r"a\b"] {
- let err = RadrootsRuntimeNamespace::new(RadrootsRuntimeNamespaceKind::App, invalid)
- .expect_err("invalid namespace component should fail");
- assert_eq!(
- err,
- RadrootsRuntimePathsError::InvalidNamespaceComponent {
- value: invalid.to_owned(),
- }
- );
- }
- }
-
- #[test]
- fn service_instance_namespace_requires_both_validated_identities() {
- let namespace = RadrootsServiceInstanceNamespace::new(
- ServiceId::new("myc").expect("service id"),
- InstanceId::new("primary-01").expect("instance id"),
- );
- assert_eq!(namespace.service_id().as_str(), "myc");
- assert_eq!(namespace.instance_id().as_str(), "primary-01");
- assert_eq!(
- namespace.relative_path(),
- PathBuf::from("services/myc/primary-01")
- );
-
- for invalid in ["../myc", "/absolute", "myc/other", "Myc"] {
- let error = RadrootsServiceInstanceNamespace::parse(invalid, "primary")
- .expect_err("invalid service path component");
- assert_identity_error_kind(error, ServiceIdentityKind::Service);
- }
- for invalid in ["../primary", "/absolute", "primary/other", "Primary"] {
- let error = RadrootsServiceInstanceNamespace::parse("myc", invalid)
- .expect_err("invalid instance path component");
- assert_identity_error_kind(error, ServiceIdentityKind::Instance);
- }
- }
-
- fn assert_identity_error_kind(error: ServiceIdentityError, expected: ServiceIdentityKind) {
- let actual = match error {
- ServiceIdentityError::Empty { kind }
- | ServiceIdentityError::TooLong { kind, .. }
- | ServiceIdentityError::InvalidBoundary { kind }
- | ServiceIdentityError::InvalidCharacter { kind } => kind,
- };
- assert_eq!(actual, expected);
- }
-}
diff --git a/crates/runtime_paths/src/platform.rs b/crates/runtime_paths/src/platform.rs
@@ -104,27 +104,9 @@ pub struct RadrootsHostEnvironment {
pub localappdata_dir: Option<PathBuf>,
}
-impl RadrootsHostEnvironment {
- #[must_use]
- pub fn from_current_process() -> Self {
- Self {
- home_dir: std::env::var_os("HOME").map(PathBuf::from),
- xdg_config_home: std::env::var_os("XDG_CONFIG_HOME").map(PathBuf::from),
- xdg_data_home: std::env::var_os("XDG_DATA_HOME").map(PathBuf::from),
- xdg_state_home: std::env::var_os("XDG_STATE_HOME").map(PathBuf::from),
- xdg_cache_home: std::env::var_os("XDG_CACHE_HOME").map(PathBuf::from),
- xdg_runtime_dir: std::env::var_os("XDG_RUNTIME_DIR").map(PathBuf::from),
- appdata_dir: std::env::var_os("APPDATA").map(PathBuf::from),
- localappdata_dir: std::env::var_os("LOCALAPPDATA").map(PathBuf::from),
- }
- }
-}
-
#[cfg(test)]
mod tests {
- use std::path::PathBuf;
-
- use super::{RadrootsHostEnvironment, RadrootsPathProfile, RadrootsPlatform};
+ use super::{RadrootsPathProfile, RadrootsPlatform};
#[test]
fn current_matches_compiled_target_platform() {
@@ -180,38 +162,4 @@ mod tests {
"mobile_native"
);
}
-
- #[test]
- fn host_environment_reads_current_process_variables() {
- let env = RadrootsHostEnvironment::from_current_process();
- assert_eq!(env.home_dir, std::env::var_os("HOME").map(PathBuf::from));
- assert_eq!(
- env.xdg_config_home,
- std::env::var_os("XDG_CONFIG_HOME").map(PathBuf::from)
- );
- assert_eq!(
- env.xdg_data_home,
- std::env::var_os("XDG_DATA_HOME").map(PathBuf::from)
- );
- assert_eq!(
- env.xdg_state_home,
- std::env::var_os("XDG_STATE_HOME").map(PathBuf::from)
- );
- assert_eq!(
- env.xdg_cache_home,
- std::env::var_os("XDG_CACHE_HOME").map(PathBuf::from)
- );
- assert_eq!(
- env.xdg_runtime_dir,
- std::env::var_os("XDG_RUNTIME_DIR").map(PathBuf::from)
- );
- assert_eq!(
- env.appdata_dir,
- std::env::var_os("APPDATA").map(PathBuf::from)
- );
- assert_eq!(
- env.localappdata_dir,
- std::env::var_os("LOCALAPPDATA").map(PathBuf::from)
- );
- }
}
diff --git a/crates/runtime_paths/src/roots.rs b/crates/runtime_paths/src/roots.rs
@@ -1,8 +1,7 @@
use std::path::{Component, Path, PathBuf};
use crate::{
- RadrootsHostEnvironment, RadrootsPathProfile, RadrootsPlatform, RadrootsRuntimeNamespace,
- RadrootsRuntimePathsError,
+ RadrootsHostEnvironment, RadrootsPathProfile, RadrootsPlatform, RadrootsRuntimePathsError,
};
const APPLICATION_DIRECTORY: &str = "radroots";
@@ -30,18 +29,18 @@ impl XdgDirectory {
}
#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct RadrootsPaths {
- pub config: PathBuf,
- pub data: PathBuf,
- pub cache: PathBuf,
- pub logs: PathBuf,
- pub run: PathBuf,
- pub secrets: PathBuf,
+pub(crate) struct RadrootsPaths {
+ pub(crate) config: PathBuf,
+ pub(crate) data: PathBuf,
+ pub(crate) cache: PathBuf,
+ pub(crate) logs: PathBuf,
+ pub(crate) run: PathBuf,
+ pub(crate) secrets: PathBuf,
}
impl RadrootsPaths {
#[must_use]
- pub fn from_base_root(base_root: impl AsRef<Path>) -> Self {
+ pub(crate) fn from_base_root(base_root: impl AsRef<Path>) -> Self {
let base_root = base_root.as_ref();
Self {
config: base_root.join("config"),
@@ -52,43 +51,6 @@ impl RadrootsPaths {
secrets: base_root.join("secrets"),
}
}
-
- #[must_use]
- pub fn namespaced(&self, namespace: &RadrootsRuntimeNamespace) -> Self {
- let relative = namespace.relative_path();
- Self {
- config: self.config.join(&relative),
- data: self.data.join(&relative),
- cache: self.cache.join(&relative),
- logs: self.logs.join(&relative),
- run: self.run.join(&relative),
- secrets: self.secrets.join(relative),
- }
- }
-}
-
-#[derive(Debug, Clone, Default, PartialEq, Eq)]
-pub struct RadrootsPathOverrides {
- pub repo_local_root: Option<PathBuf>,
- pub mobile_roots: Option<RadrootsPaths>,
-}
-
-impl RadrootsPathOverrides {
- #[must_use]
- pub fn repo_local(base_root: impl Into<PathBuf>) -> Self {
- Self {
- repo_local_root: Some(base_root.into()),
- mobile_roots: None,
- }
- }
-
- #[must_use]
- pub fn mobile(roots: RadrootsPaths) -> Self {
- Self {
- repo_local_root: None,
- mobile_roots: Some(roots),
- }
- }
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -107,49 +69,30 @@ impl RadrootsPathResolver {
}
#[must_use]
- pub fn current() -> Self {
- Self::new(
- RadrootsPlatform::current(),
- RadrootsHostEnvironment::from_current_process(),
- )
- }
-
- #[must_use]
pub fn platform(&self) -> RadrootsPlatform {
self.platform
}
- pub fn resolve(
+ pub(crate) fn resolve(
&self,
profile: RadrootsPathProfile,
- overrides: &RadrootsPathOverrides,
+ repo_local_root: Option<&Path>,
) -> Result<RadrootsPaths, RadrootsRuntimePathsError> {
match profile {
RadrootsPathProfile::InteractiveUser => self.resolve_interactive_user(),
RadrootsPathProfile::ServiceHost => self.resolve_service_host(),
RadrootsPathProfile::RepoLocal => {
- let root = overrides
- .repo_local_root
- .as_deref()
- .ok_or(RadrootsRuntimePathsError::MissingRepoLocalRoot)?;
+ let root =
+ repo_local_root.ok_or(RadrootsRuntimePathsError::MissingRepoLocalRoot)?;
validate_repo_local_root(root)?;
Ok(RadrootsPaths::from_base_root(root))
}
- RadrootsPathProfile::MobileNative => match self.platform {
- RadrootsPlatform::Android | RadrootsPlatform::Ios => overrides
- .mobile_roots
- .clone()
- .ok_or(RadrootsRuntimePathsError::MissingMobileRoots),
- RadrootsPlatform::Linux
- | RadrootsPlatform::Macos
- | RadrootsPlatform::Windows
- | RadrootsPlatform::Other => {
- Err(RadrootsRuntimePathsError::UnsupportedProfilePlatform {
- profile,
- platform: self.platform,
- })
- }
- },
+ RadrootsPathProfile::MobileNative => {
+ Err(RadrootsRuntimePathsError::UnsupportedProfilePlatform {
+ profile,
+ platform: self.platform,
+ })
+ }
}
}
@@ -295,127 +238,57 @@ pub(crate) fn validate_repo_local_root(root: &Path) -> Result<(), RadrootsRuntim
#[cfg(test)]
mod tests {
- use std::path::PathBuf;
+ use std::path::{Path, PathBuf};
- use super::{RadrootsPathOverrides, RadrootsPathResolver, RadrootsPaths};
+ use super::{RadrootsPathResolver, RadrootsPaths};
use crate::{
RadrootsHostEnvironment, RadrootsPathProfile, RadrootsPlatform, RadrootsRuntimePathsError,
};
#[test]
- fn path_override_helpers_only_populate_their_owned_slot() {
- let repo_local = RadrootsPathOverrides::repo_local("/repo/.local/radroots");
- assert_eq!(
- repo_local.repo_local_root,
- Some(PathBuf::from("/repo/.local/radroots"))
- );
- assert!(repo_local.mobile_roots.is_none());
-
- let mobile_roots = RadrootsPaths::from_base_root("/sandbox");
- let mobile = RadrootsPathOverrides::mobile(mobile_roots.clone());
- assert!(mobile.repo_local_root.is_none());
- assert_eq!(mobile.mobile_roots, Some(mobile_roots));
- }
-
- #[test]
- fn repo_local_root_rejects_missing_relative_root_and_parent_traversal() {
+ fn repo_local_is_explicit_validated_and_one_base() {
let resolver =
RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default());
-
assert_eq!(
resolver
- .resolve(
- RadrootsPathProfile::RepoLocal,
- &RadrootsPathOverrides::default(),
- )
+ .resolve(RadrootsPathProfile::RepoLocal, None)
.expect_err("missing root"),
RadrootsRuntimePathsError::MissingRepoLocalRoot
);
-
- for root in [
- "",
- ".",
- "relative/root",
- "../escape",
- "/",
- "/repo/../escape",
- ] {
+ for invalid in ["", ".", "relative/root", "/", "/repo/../escape"] {
assert_eq!(
resolver
- .resolve(
- RadrootsPathProfile::RepoLocal,
- &RadrootsPathOverrides::repo_local(root),
- )
- .expect_err("invalid repo-local root"),
- RadrootsRuntimePathsError::InvalidRepoLocalRoot,
- "accepted invalid repo-local root `{root}`"
+ .resolve(RadrootsPathProfile::RepoLocal, Some(Path::new(invalid)))
+ .expect_err("invalid root"),
+ RadrootsRuntimePathsError::InvalidRepoLocalRoot
);
}
- }
-
- #[test]
- fn resolver_current_uses_process_platform_and_environment() {
- let resolver = RadrootsPathResolver::current();
- assert_eq!(resolver.platform(), RadrootsPlatform::current());
- assert_eq!(
- resolver,
- RadrootsPathResolver::new(
- RadrootsPlatform::current(),
- RadrootsHostEnvironment::from_current_process()
- )
- );
- }
-
- #[test]
- fn linux_interactive_uses_exact_config_data_state_cache_and_runtime_roots() {
- let resolver = RadrootsPathResolver::new(
- RadrootsPlatform::Linux,
- RadrootsHostEnvironment {
- xdg_config_home: Some(PathBuf::from("/xdg/config")),
- xdg_data_home: Some(PathBuf::from("/xdg/data")),
- xdg_state_home: Some(PathBuf::from("/xdg/state")),
- xdg_cache_home: Some(PathBuf::from("/xdg/cache")),
- xdg_runtime_dir: Some(PathBuf::from("/xdg/run")),
- ..RadrootsHostEnvironment::default()
- },
- );
-
assert_eq!(
resolver
.resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
+ RadrootsPathProfile::RepoLocal,
+ Some(Path::new("/repo/.local/radroots")),
)
- .expect("configured XDG roots"),
- RadrootsPaths {
- config: PathBuf::from("/xdg/config/radroots"),
- data: PathBuf::from("/xdg/data/radroots"),
- cache: PathBuf::from("/xdg/cache/radroots"),
- logs: PathBuf::from("/xdg/state/radroots/logs"),
- run: PathBuf::from("/xdg/run/radroots"),
- secrets: PathBuf::from("/xdg/config/radroots/secrets"),
- }
+ .expect("repo roots"),
+ RadrootsPaths::from_base_root("/repo/.local/radroots")
);
}
#[test]
- fn linux_interactive_uses_xdg_home_defaults_but_never_invents_runtime() {
+ fn linux_interactive_uses_injected_xdg_and_home_defaults() {
let resolver = RadrootsPathResolver::new(
RadrootsPlatform::Linux,
RadrootsHostEnvironment {
home_dir: Some(PathBuf::from("/home/treesap")),
+ xdg_config_home: Some(PathBuf::from("relative-ignored")),
xdg_runtime_dir: Some(PathBuf::from("/run/user/1000")),
..RadrootsHostEnvironment::default()
},
);
-
assert_eq!(
resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect("defaulted XDG roots"),
+ .resolve(RadrootsPathProfile::InteractiveUser, None)
+ .expect("linux interactive"),
RadrootsPaths {
config: PathBuf::from("/home/treesap/.config/radroots"),
data: PathBuf::from("/home/treesap/.local/share/radroots"),
@@ -425,8 +298,11 @@ mod tests {
secrets: PathBuf::from("/home/treesap/.config/radroots/secrets"),
}
);
+ }
- let missing_runtime = RadrootsPathResolver::new(
+ #[test]
+ fn linux_interactive_never_invents_runtime_root() {
+ let resolver = RadrootsPathResolver::new(
RadrootsPlatform::Linux,
RadrootsHostEnvironment {
home_dir: Some(PathBuf::from("/home/treesap")),
@@ -434,241 +310,74 @@ mod tests {
},
);
assert_eq!(
- missing_runtime
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("XDG runtime has no home fallback"),
+ resolver
+ .resolve(RadrootsPathProfile::InteractiveUser, None)
+ .expect_err("runtime root is required"),
RadrootsRuntimePathsError::MissingXdgRuntimeDir
);
}
#[test]
- fn linux_interactive_ignores_empty_and_relative_xdg_directories() {
- let valid = RadrootsHostEnvironment {
- home_dir: Some(PathBuf::from("/home/treesap")),
- xdg_config_home: Some(PathBuf::from("/xdg/config")),
- xdg_data_home: Some(PathBuf::from("/xdg/data")),
- xdg_state_home: Some(PathBuf::from("/xdg/state")),
- xdg_cache_home: Some(PathBuf::from("/xdg/cache")),
- xdg_runtime_dir: Some(PathBuf::from("/xdg/run")),
- ..RadrootsHostEnvironment::default()
- };
- for (environment, expected) in [
- (
- RadrootsHostEnvironment {
- xdg_config_home: Some(PathBuf::new()),
- ..valid.clone()
- },
- PathBuf::from("/home/treesap/.config/radroots"),
- ),
- (
- RadrootsHostEnvironment {
- xdg_config_home: Some(PathBuf::from("relative/config")),
- ..valid.clone()
- },
- PathBuf::from("/home/treesap/.config/radroots"),
- ),
- (
- RadrootsHostEnvironment {
- xdg_data_home: Some(PathBuf::new()),
- ..valid.clone()
- },
- PathBuf::from("/home/treesap/.local/share/radroots"),
- ),
- (
- RadrootsHostEnvironment {
- xdg_data_home: Some(PathBuf::from("relative/data")),
- ..valid.clone()
- },
- PathBuf::from("/home/treesap/.local/share/radroots"),
- ),
- (
- RadrootsHostEnvironment {
- xdg_state_home: Some(PathBuf::new()),
- ..valid.clone()
- },
- PathBuf::from("/home/treesap/.local/state/radroots/logs"),
- ),
- (
- RadrootsHostEnvironment {
- xdg_state_home: Some(PathBuf::from("relative/state")),
- ..valid.clone()
- },
- PathBuf::from("/home/treesap/.local/state/radroots/logs"),
- ),
- (
- RadrootsHostEnvironment {
- xdg_cache_home: Some(PathBuf::new()),
- ..valid.clone()
- },
- PathBuf::from("/home/treesap/.cache/radroots"),
- ),
- (
- RadrootsHostEnvironment {
- xdg_cache_home: Some(PathBuf::from("relative/cache")),
- ..valid.clone()
- },
- PathBuf::from("/home/treesap/.cache/radroots"),
- ),
- ] {
- let resolver = RadrootsPathResolver::new(RadrootsPlatform::Linux, environment);
- let roots = resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect("invalid optional XDG directory is ignored");
- assert!(
- [roots.config, roots.data, roots.logs, roots.cache].contains(&expected),
- "expected fallback root {expected:?}"
- );
- }
-
- for xdg_runtime_dir in [Some(PathBuf::new()), Some(PathBuf::from("relative/run"))] {
+ fn home_derived_roots_require_absolute_home() {
+ for platform in [RadrootsPlatform::Linux, RadrootsPlatform::Macos] {
let resolver = RadrootsPathResolver::new(
- RadrootsPlatform::Linux,
+ platform,
RadrootsHostEnvironment {
- xdg_runtime_dir,
- ..valid.clone()
- },
- );
- assert_eq!(
- resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("invalid XDG runtime is treated as missing"),
- RadrootsRuntimePathsError::MissingXdgRuntimeDir
- );
- }
- }
-
- #[test]
- fn interactive_home_derived_roots_require_an_absolute_nonempty_home() {
- for home_dir in [Some(PathBuf::new()), Some(PathBuf::from("relative/home"))] {
- let linux = RadrootsPathResolver::new(
- RadrootsPlatform::Linux,
- RadrootsHostEnvironment {
- home_dir: home_dir.clone(),
+ home_dir: Some(PathBuf::from("relative")),
xdg_runtime_dir: Some(PathBuf::from("/run/user/1000")),
..RadrootsHostEnvironment::default()
},
);
assert_eq!(
- linux
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("Linux HOME defaults require an absolute HOME"),
- RadrootsRuntimePathsError::InvalidHomeDir {
- platform: RadrootsPlatform::Linux,
- }
- );
-
- let macos = RadrootsPathResolver::new(
- RadrootsPlatform::Macos,
- RadrootsHostEnvironment {
- home_dir,
- ..RadrootsHostEnvironment::default()
- },
- );
- assert_eq!(
- macos
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("macOS native roots require an absolute HOME"),
- RadrootsRuntimePathsError::InvalidHomeDir {
- platform: RadrootsPlatform::Macos,
- }
+ resolver
+ .resolve(RadrootsPathProfile::InteractiveUser, None)
+ .expect_err("relative home"),
+ RadrootsRuntimePathsError::InvalidHomeDir { platform }
);
}
}
#[test]
- fn macos_interactive_uses_native_library_roots_and_ignores_xdg() {
- let resolver = RadrootsPathResolver::new(
- RadrootsPlatform::Macos,
- RadrootsHostEnvironment {
- home_dir: Some(PathBuf::from("/Users/treesap")),
- xdg_config_home: Some(PathBuf::from("relative/config")),
- xdg_data_home: Some(PathBuf::from("relative/data")),
- xdg_state_home: Some(PathBuf::from("relative/state")),
- xdg_cache_home: Some(PathBuf::from("relative/cache")),
- xdg_runtime_dir: Some(PathBuf::from("relative/run")),
- ..RadrootsHostEnvironment::default()
- },
- );
-
- assert_eq!(
- resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect("macOS native roots"),
- RadrootsPaths {
- config: PathBuf::from("/Users/treesap/Library/Application Support/Radroots/config",),
- data: PathBuf::from("/Users/treesap/Library/Application Support/Radroots/data",),
- cache: PathBuf::from("/Users/treesap/Library/Caches/Radroots"),
- logs: PathBuf::from("/Users/treesap/Library/Logs/Radroots"),
- run: PathBuf::from("/Users/treesap/Library/Application Support/Radroots/run",),
- secrets: PathBuf::from(
- "/Users/treesap/Library/Application Support/Radroots/secrets",
- ),
- }
- );
- }
-
- #[test]
- fn mobile_profile_is_rejected_on_non_mobile_platforms() {
+ fn service_host_linux_uses_canonical_roots() {
let resolver =
RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default());
-
- let err = resolver
- .resolve(
- RadrootsPathProfile::MobileNative,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("mobile profile should be rejected on linux");
-
assert_eq!(
- err,
- RadrootsRuntimePathsError::UnsupportedProfilePlatform {
- profile: RadrootsPathProfile::MobileNative,
- platform: RadrootsPlatform::Linux,
+ resolver
+ .resolve(RadrootsPathProfile::ServiceHost, None)
+ .expect("service host"),
+ RadrootsPaths {
+ config: PathBuf::from("/etc/radroots"),
+ data: PathBuf::from("/var/lib/radroots"),
+ cache: PathBuf::from("/var/cache/radroots"),
+ logs: PathBuf::from("/var/log/radroots"),
+ run: PathBuf::from("/run/radroots"),
+ secrets: PathBuf::from("/etc/radroots/secrets"),
}
);
}
#[test]
- fn interactive_user_is_rejected_on_mobile_platforms() {
- for platform in [RadrootsPlatform::Android, RadrootsPlatform::Ios] {
+ fn unsupported_profile_platform_pairs_fail_closed() {
+ for platform in [
+ RadrootsPlatform::Macos,
+ RadrootsPlatform::Windows,
+ RadrootsPlatform::Android,
+ RadrootsPlatform::Ios,
+ RadrootsPlatform::Other,
+ ] {
let resolver = RadrootsPathResolver::new(platform, RadrootsHostEnvironment::default());
- let err = resolver
- .resolve(
- RadrootsPathProfile::InteractiveUser,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("interactive_user should be unsupported on mobile");
assert_eq!(
- err,
+ resolver
+ .resolve(RadrootsPathProfile::ServiceHost, None)
+ .expect_err("unsupported service host"),
RadrootsRuntimePathsError::UnsupportedProfilePlatform {
- profile: RadrootsPathProfile::InteractiveUser,
+ profile: RadrootsPathProfile::ServiceHost,
platform,
}
);
}
- }
-
- #[test]
- fn service_host_is_rejected_outside_linux() {
for platform in [
+ RadrootsPlatform::Linux,
RadrootsPlatform::Macos,
RadrootsPlatform::Windows,
RadrootsPlatform::Android,
@@ -676,16 +385,12 @@ mod tests {
RadrootsPlatform::Other,
] {
let resolver = RadrootsPathResolver::new(platform, RadrootsHostEnvironment::default());
- let err = resolver
- .resolve(
- RadrootsPathProfile::ServiceHost,
- &RadrootsPathOverrides::default(),
- )
- .expect_err("service_host should be unsupported outside linux");
assert_eq!(
- err,
+ resolver
+ .resolve(RadrootsPathProfile::MobileNative, None)
+ .expect_err("mobile roots require a product-owned adapter"),
RadrootsRuntimePathsError::UnsupportedProfilePlatform {
- profile: RadrootsPathProfile::ServiceHost,
+ profile: RadrootsPathProfile::MobileNative,
platform,
}
);
diff --git a/crates/runtime_paths/src/service.rs b/crates/runtime_paths/src/service.rs
@@ -1,17 +1,6 @@
-use std::{
- ffi::OsString,
- path::{Path, PathBuf},
-};
+use std::path::{Path, PathBuf};
-use serde::Serialize;
-use thiserror::Error;
-
-use crate::roots::validate_repo_local_root;
-use crate::{
- InstanceId, RadrootsPathOverrides, RadrootsPathProfile, RadrootsPathResolver, RadrootsPaths,
- RadrootsRuntimeNamespace, RadrootsRuntimePathsError, RadrootsServiceInstanceNamespace,
- ServiceId,
-};
+use crate::{InstanceId, ServiceId, roots::RadrootsPaths};
/// Canonical directories owned by one validated service instance.
///
@@ -44,9 +33,12 @@ pub struct RadrootsServiceInstancePaths {
impl RadrootsServiceInstancePaths {
pub(crate) fn from_resolved_roots(
roots: &RadrootsPaths,
- namespace: &RadrootsServiceInstanceNamespace,
+ service: &ServiceId,
+ instance: &InstanceId,
) -> Self {
- let relative = namespace.relative_path();
+ let relative = Path::new("services")
+ .join(service.as_str())
+ .join(instance.as_str());
Self {
config: roots.config.join(&relative),
state: roots.data.join(&relative),
@@ -88,664 +80,28 @@ impl RadrootsServiceInstancePaths {
}
}
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct RadrootsRuntimePathSelection {
- pub profile: RadrootsPathProfile,
- pub profile_source: String,
- pub repo_local_root: Option<PathBuf>,
- pub repo_local_root_source: Option<String>,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct RadrootsRuntimePathConfigEntry {
- pub key: String,
- pub value: String,
- pub source_label: String,
-}
-
-impl RadrootsRuntimePathConfigEntry {
- #[must_use]
- pub fn new(
- key: impl Into<String>,
- value: impl Into<String>,
- source_label: impl Into<String>,
- ) -> Self {
- Self {
- key: key.into(),
- value: value.into(),
- source_label: source_label.into(),
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
-pub struct RadrootsRuntimeSelectionContract {
- pub active_profile: String,
- pub allowed_profiles: Vec<String>,
- pub path_overrides: RadrootsRuntimeSelectionOverrideContract,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
-pub struct RadrootsRuntimeSelectionOverrideContract {
- pub profile_source: String,
- pub root_source: String,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub repo_local_root: Option<PathBuf>,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub repo_local_root_source: Option<String>,
- pub subordinate_path_override_source: String,
- pub subordinate_path_override_keys: Vec<String>,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
-pub struct RadrootsRuntimePathPolicyContract {
- pub canonical_root_selection: String,
- pub canonical_subordinate_path_override: String,
- pub leaf_path_env_posture: String,
-}
-
-impl RadrootsRuntimePathPolicyContract {
- pub fn new(
- canonical_root_selection: &str,
- canonical_subordinate_path_override: &str,
- leaf_path_env_posture: &str,
- ) -> Self {
- Self {
- canonical_root_selection: canonical_root_selection.to_owned(),
- canonical_subordinate_path_override: canonical_subordinate_path_override.to_owned(),
- leaf_path_env_posture: leaf_path_env_posture.to_owned(),
- }
- }
-}
-
-#[derive(Debug, Error, Clone, PartialEq, Eq)]
-pub enum RadrootsRuntimePathSelectionError {
- #[error("{env_var} must be valid utf-8 when set")]
- NonUnicodeEnv { env_var: String },
-
- #[error(
- "{env_var} must be `interactive_user`, `service_host`, or `repo_local`; found `{value}`"
- )]
- InvalidProfileEnv { env_var: String, value: String },
-
- #[error(
- "profile must be `interactive_user`, `service_host`, `repo_local`, or `mobile_native`; found `{value}`"
- )]
- InvalidProfileValue { value: String },
-
- #[error("{repo_local_root_env} must be set when {profile_env}=repo_local")]
- MissingRepoLocalRoot {
- profile_env: String,
- repo_local_root_env: String,
- },
-
- #[error(transparent)]
- Paths(#[from] RadrootsRuntimePathsError),
-}
-
-impl RadrootsRuntimePathSelection {
- pub fn caller(profile: RadrootsPathProfile, repo_local_root: Option<PathBuf>) -> Self {
- Self {
- profile,
- profile_source: "caller".to_owned(),
- repo_local_root_source: repo_local_root.as_ref().map(|_| "caller".to_owned()),
- repo_local_root,
- }
- }
-
- pub fn from_profile_value(
- profile: &str,
- repo_local_root: Option<PathBuf>,
- ) -> Result<Self, RadrootsRuntimePathSelectionError> {
- Ok(Self::caller(parse_profile_value(profile)?, repo_local_root))
- }
-
- pub fn from_config_entries(
- profile_entry: Option<RadrootsRuntimePathConfigEntry>,
- repo_local_root_entry: Option<RadrootsRuntimePathConfigEntry>,
- default_profile: RadrootsPathProfile,
- ) -> Result<Self, RadrootsRuntimePathSelectionError> {
- let (profile, profile_source) = match profile_entry {
- Some(entry) => (
- parse_profile(entry.key.as_str(), entry.value.as_str())?,
- entry.source_label,
- ),
- None => (default_profile, "default".to_owned()),
- };
- let (repo_local_root, repo_local_root_source) = match repo_local_root_entry {
- Some(entry) => (Some(PathBuf::from(entry.value)), Some(entry.source_label)),
- None => (None, None),
- };
- Ok(Self {
- profile,
- profile_source,
- repo_local_root,
- repo_local_root_source,
- })
- }
-
- pub fn from_env(
- profile_env: &'static str,
- repo_local_root_env: &'static str,
- default_profile: RadrootsPathProfile,
- ) -> Result<Self, RadrootsRuntimePathSelectionError> {
- Self::from_env_values(
- profile_env,
- std::env::var(profile_env),
- repo_local_root_env,
- std::env::var_os(repo_local_root_env),
- default_profile,
- )
- }
-
- fn from_env_values(
- profile_env: &'static str,
- profile_value: Result<String, std::env::VarError>,
- repo_local_root_env: &'static str,
- repo_local_root_raw: Option<OsString>,
- default_profile: RadrootsPathProfile,
- ) -> Result<Self, RadrootsRuntimePathSelectionError> {
- let (profile, profile_source) = match profile_value {
- Ok(value) => (
- parse_profile(profile_env, value.as_str())?,
- format!("process_env:{profile_env}"),
- ),
- Err(std::env::VarError::NotPresent) => (default_profile, "default".to_owned()),
- Err(std::env::VarError::NotUnicode(_)) => {
- return Err(RadrootsRuntimePathSelectionError::NonUnicodeEnv {
- env_var: profile_env.to_owned(),
- });
- }
- };
- let repo_local_root = repo_local_root_raw.as_ref().map(PathBuf::from);
- Ok(Self {
- profile,
- profile_source,
- repo_local_root,
- repo_local_root_source: repo_local_root_raw
- .as_ref()
- .map(|_| format!("process_env:{repo_local_root_env}")),
- })
- }
-
- pub fn root_source(&self) -> &'static str {
- match self.profile {
- RadrootsPathProfile::InteractiveUser => "host_defaults",
- RadrootsPathProfile::ServiceHost => "service_host_defaults",
- RadrootsPathProfile::RepoLocal => "repo_local_root",
- RadrootsPathProfile::MobileNative => "mobile_native_defaults",
- }
- }
-
- pub fn overrides(
- &self,
- profile_env: &'static str,
- repo_local_root_env: &'static str,
- ) -> Result<RadrootsPathOverrides, RadrootsRuntimePathSelectionError> {
- self.overrides_with_labels(profile_env, repo_local_root_env)
- }
-
- pub fn caller_overrides(
- &self,
- ) -> Result<RadrootsPathOverrides, RadrootsRuntimePathSelectionError> {
- self.overrides_with_labels("caller_profile", "caller_repo_local_root")
- }
-
- pub fn contract(
- &self,
- allowed_profiles: &[&str],
- subordinate_path_override_source: &str,
- subordinate_path_override_keys: &[&str],
- ) -> RadrootsRuntimeSelectionContract {
- RadrootsRuntimeSelectionContract {
- active_profile: self.profile.to_string(),
- allowed_profiles: allowed_profiles
- .iter()
- .map(|entry| (*entry).to_owned())
- .collect(),
- path_overrides: RadrootsRuntimeSelectionOverrideContract {
- profile_source: self.profile_source.clone(),
- root_source: self.root_source().to_owned(),
- repo_local_root: self.repo_local_root.clone(),
- repo_local_root_source: self.repo_local_root_source.clone(),
- subordinate_path_override_source: subordinate_path_override_source.to_owned(),
- subordinate_path_override_keys: subordinate_path_override_keys
- .iter()
- .map(|entry| (*entry).to_owned())
- .collect(),
- },
- }
- }
-
- fn overrides_with_labels(
- &self,
- profile_label: &str,
- repo_local_root_label: &str,
- ) -> Result<RadrootsPathOverrides, RadrootsRuntimePathSelectionError> {
- match self.profile {
- RadrootsPathProfile::RepoLocal => {
- let Some(repo_local_root) = self.repo_local_root.as_ref() else {
- return Err(RadrootsRuntimePathSelectionError::MissingRepoLocalRoot {
- profile_env: profile_label.to_owned(),
- repo_local_root_env: repo_local_root_label.to_owned(),
- });
- };
- validate_repo_local_root(repo_local_root)?;
- Ok(RadrootsPathOverrides::repo_local(repo_local_root))
- }
- _ => Ok(RadrootsPathOverrides::default()),
- }
- }
-
- pub fn resolve_service_roots(
- &self,
- resolver: &RadrootsPathResolver,
- service_id: &str,
- profile_env: &'static str,
- repo_local_root_env: &'static str,
- ) -> Result<RadrootsPaths, RadrootsRuntimePathSelectionError> {
- let namespace = RadrootsRuntimeNamespace::service(service_id)?;
- let overrides = self.overrides(profile_env, repo_local_root_env)?;
- let roots = resolver.resolve(self.profile, &overrides)?;
- Ok(roots.namespaced(&namespace))
- }
-
- pub fn resolve_service_instance_paths(
- &self,
- resolver: &RadrootsPathResolver,
- service_id: &ServiceId,
- instance_id: &InstanceId,
- profile_env: &'static str,
- repo_local_root_env: &'static str,
- ) -> Result<RadrootsServiceInstancePaths, RadrootsRuntimePathSelectionError> {
- let namespace =
- RadrootsServiceInstanceNamespace::new(service_id.clone(), instance_id.clone());
- let overrides = self.overrides(profile_env, repo_local_root_env)?;
- let roots = resolver.resolve(self.profile, &overrides)?;
- Ok(RadrootsServiceInstancePaths::from_resolved_roots(
- &roots, &namespace,
- ))
- }
-}
-
-fn parse_profile(
- env_var: &str,
- value: &str,
-) -> Result<RadrootsPathProfile, RadrootsRuntimePathSelectionError> {
- parse_profile_value(value).map_err(|_| RadrootsRuntimePathSelectionError::InvalidProfileEnv {
- env_var: env_var.to_owned(),
- value: value.to_owned(),
- })
-}
-
-fn parse_profile_value(
- value: &str,
-) -> Result<RadrootsPathProfile, RadrootsRuntimePathSelectionError> {
- match value {
- "interactive_user" => Ok(RadrootsPathProfile::InteractiveUser),
- "service_host" => Ok(RadrootsPathProfile::ServiceHost),
- "repo_local" => Ok(RadrootsPathProfile::RepoLocal),
- "mobile_native" => Ok(RadrootsPathProfile::MobileNative),
- other => Err(RadrootsRuntimePathSelectionError::InvalidProfileValue {
- value: other.to_owned(),
- }),
- }
-}
-
#[cfg(test)]
mod tests {
use std::path::PathBuf;
- use crate::{
- RadrootsHostEnvironment, RadrootsPathProfile, RadrootsPathResolver, RadrootsPlatform,
- };
-
- use super::{
- RadrootsRuntimePathConfigEntry, RadrootsRuntimePathPolicyContract,
- RadrootsRuntimePathSelection, RadrootsRuntimePathSelectionError,
- };
- use crate::{InstanceId, ServiceId};
+ use super::RadrootsServiceInstancePaths;
+ use crate::{InstanceId, ServiceId, roots::RadrootsPaths};
#[test]
- fn caller_selection_preserves_profile_and_sources() {
- let selection =
- RadrootsRuntimePathSelection::caller(RadrootsPathProfile::InteractiveUser, None);
- assert_eq!(selection.profile, RadrootsPathProfile::InteractiveUser);
- assert_eq!(selection.profile_source, "caller");
- assert_eq!(selection.repo_local_root, None);
- assert_eq!(selection.repo_local_root_source, None);
- assert_eq!(selection.root_source(), "host_defaults");
-
- let overrides = selection
- .caller_overrides()
- .expect("non-repo-local caller overrides should be empty");
- assert_eq!(overrides.repo_local_root, None);
-
- let service_selection =
- RadrootsRuntimePathSelection::caller(RadrootsPathProfile::ServiceHost, None);
- assert_eq!(service_selection.root_source(), "service_host_defaults");
- }
-
- #[test]
- fn caller_selection_marks_repo_local_source() {
- let selection = RadrootsRuntimePathSelection::caller(
- RadrootsPathProfile::RepoLocal,
- Some(PathBuf::from("/repo/.local/radroots")),
- );
-
- assert_eq!(selection.profile_source, "caller");
- assert_eq!(selection.repo_local_root_source.as_deref(), Some("caller"));
- assert_eq!(selection.root_source(), "repo_local_root");
-
- let overrides = selection
- .caller_overrides()
- .expect("caller overrides should use repo-local root");
- assert_eq!(
- overrides.repo_local_root,
- Some(PathBuf::from("/repo/.local/radroots"))
- );
- }
-
- #[test]
- fn resolve_service_roots_uses_repo_local_override() {
- let selection = RadrootsRuntimePathSelection::caller(
- RadrootsPathProfile::RepoLocal,
- Some(PathBuf::from("/repo/.local/radroots")),
- );
- let resolver =
- RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default());
-
- let roots = selection
- .resolve_service_roots(&resolver, "radrootsd", "PROFILE_ENV", "ROOT_ENV")
- .expect("service roots");
-
- assert_eq!(
- roots.config,
- PathBuf::from("/repo/.local/radroots/config/services/radrootsd")
- );
- assert_eq!(
- roots.data,
- PathBuf::from("/repo/.local/radroots/data/services/radrootsd")
- );
- assert_eq!(
- roots.logs,
- PathBuf::from("/repo/.local/radroots/logs/services/radrootsd")
- );
- assert_eq!(
- roots.run,
- PathBuf::from("/repo/.local/radroots/run/services/radrootsd")
- );
- assert_eq!(
- roots.secrets,
- PathBuf::from("/repo/.local/radroots/secrets/services/radrootsd")
- );
- }
-
- #[test]
- fn resolve_myc_and_rhi_instance_paths_use_one_repo_local_base() {
- let selection = RadrootsRuntimePathSelection::caller(
- RadrootsPathProfile::RepoLocal,
- Some(PathBuf::from("/repo/.local/radroots")),
- );
- let resolver =
- RadrootsPathResolver::new(RadrootsPlatform::Linux, RadrootsHostEnvironment::default());
- for (service, instance) in [("myc", "primary"), ("rhi", "west-01")] {
- let service_id = ServiceId::new(service).expect("service id");
- let instance_id = InstanceId::new(instance).expect("instance id");
- let paths = selection
- .resolve_service_instance_paths(
- &resolver,
- &service_id,
- &instance_id,
- "PROFILE_ENV",
- "ROOT_ENV",
- )
- .expect("service instance paths");
- let suffix = format!("services/{service}/{instance}");
-
- assert_eq!(
- paths.config(),
- PathBuf::from("/repo/.local/radroots/config").join(&suffix)
- );
- assert_eq!(
- paths.state(),
- PathBuf::from("/repo/.local/radroots/data").join(&suffix)
- );
- assert_eq!(
- paths.cache(),
- PathBuf::from("/repo/.local/radroots/cache").join(&suffix)
- );
- assert_eq!(
- paths.logs(),
- PathBuf::from("/repo/.local/radroots/logs").join(&suffix)
- );
- assert_eq!(
- paths.run(),
- PathBuf::from("/repo/.local/radroots/run").join(&suffix)
- );
- assert_eq!(
- paths.secrets(),
- PathBuf::from("/repo/.local/radroots/secrets").join(&suffix)
- );
- }
- }
-
- #[test]
- fn overrides_require_repo_local_root_for_repo_local_profile() {
- let selection = RadrootsRuntimePathSelection::caller(RadrootsPathProfile::RepoLocal, None);
- let err = selection
- .overrides("RADROOTS_TEST_PROFILE", "RADROOTS_TEST_ROOT")
- .expect_err("repo local root");
-
- assert_eq!(
- err,
- RadrootsRuntimePathSelectionError::MissingRepoLocalRoot {
- profile_env: "RADROOTS_TEST_PROFILE".to_owned(),
- repo_local_root_env: "RADROOTS_TEST_ROOT".to_owned(),
- }
- );
- }
-
- #[test]
- fn repo_local_selection_rejects_relative_empty_and_escaping_roots() {
- for root in [
- "",
- ".",
- "relative/root",
- "../escape",
- "/",
- "/repo/../escape",
- ] {
- let selection = RadrootsRuntimePathSelection::caller(
- RadrootsPathProfile::RepoLocal,
- Some(PathBuf::from(root)),
- );
- assert_eq!(
- selection
- .caller_overrides()
- .expect_err("invalid caller root"),
- RadrootsRuntimePathSelectionError::Paths(
- crate::RadrootsRuntimePathsError::InvalidRepoLocalRoot
- ),
- "accepted invalid repo-local selection `{root}`"
- );
- }
- }
-
- #[test]
- fn profile_value_selection_accepts_mobile_native() {
- let selection = RadrootsRuntimePathSelection::from_profile_value("mobile_native", None)
- .expect("mobile native profile");
-
- assert_eq!(selection.profile, RadrootsPathProfile::MobileNative);
- assert_eq!(selection.profile_source, "caller");
- assert_eq!(selection.root_source(), "mobile_native_defaults");
-
- let selection = RadrootsRuntimePathSelection::from_profile_value("interactive_user", None)
- .expect("interactive profile");
- assert_eq!(selection.profile, RadrootsPathProfile::InteractiveUser);
-
- let selection = RadrootsRuntimePathSelection::from_profile_value("service_host", None)
- .expect("service-host profile");
- assert_eq!(selection.profile, RadrootsPathProfile::ServiceHost);
- }
-
- #[test]
- fn env_selection_covers_absent_present_and_error_paths() {
- let selection = RadrootsRuntimePathSelection::from_env(
- "RADROOTS_RUNTIME_PATHS_TEST_UNSET_PROFILE_DFA3ED5D",
- "RADROOTS_RUNTIME_PATHS_TEST_UNSET_ROOT_DFA3ED5D",
- RadrootsPathProfile::ServiceHost,
- )
- .expect("absent env selection should use default profile");
- assert_eq!(selection.profile, RadrootsPathProfile::ServiceHost);
- assert_eq!(selection.profile_source, "default");
- assert_eq!(selection.repo_local_root, None);
- assert_eq!(selection.repo_local_root_source, None);
-
- let selection = RadrootsRuntimePathSelection::from_env_values(
- "RADROOTS_TEST_PROFILE",
- Ok("repo_local".to_owned()),
- "RADROOTS_TEST_ROOT",
- Some(std::ffi::OsString::from("/repo/.local/radroots")),
- RadrootsPathProfile::InteractiveUser,
- )
- .expect("present env values should select repo-local profile");
- assert_eq!(selection.profile, RadrootsPathProfile::RepoLocal);
- assert_eq!(
- selection.profile_source,
- "process_env:RADROOTS_TEST_PROFILE"
- );
- assert_eq!(
- selection.repo_local_root,
- Some(PathBuf::from("/repo/.local/radroots"))
- );
- assert_eq!(
- selection.repo_local_root_source.as_deref(),
- Some("process_env:RADROOTS_TEST_ROOT")
- );
-
- let err = RadrootsRuntimePathSelection::from_env_values(
- "RADROOTS_TEST_PROFILE",
- Err(std::env::VarError::NotUnicode(std::ffi::OsString::from(
- "not-unicode",
- ))),
- "RADROOTS_TEST_ROOT",
- None,
- RadrootsPathProfile::InteractiveUser,
- )
- .expect_err("non-unicode profile env should fail");
- assert_eq!(
- err,
- RadrootsRuntimePathSelectionError::NonUnicodeEnv {
- env_var: "RADROOTS_TEST_PROFILE".to_owned()
- }
- );
-
- let err = RadrootsRuntimePathSelection::from_env_values(
- "RADROOTS_TEST_PROFILE",
- Ok("unknown".to_owned()),
- "RADROOTS_TEST_ROOT",
- None,
- RadrootsPathProfile::InteractiveUser,
- )
- .expect_err("invalid profile env should fail");
- assert_eq!(
- err,
- RadrootsRuntimePathSelectionError::InvalidProfileEnv {
- env_var: "RADROOTS_TEST_PROFILE".to_owned(),
- value: "unknown".to_owned()
- }
- );
- }
-
- #[test]
- fn config_entry_selection_preserves_sources() {
- let selection = RadrootsRuntimePathSelection::from_config_entries(
- Some(RadrootsRuntimePathConfigEntry::new(
- "RADROOTS_CLI_PATHS_PROFILE",
- "repo_local",
- "env_file:RADROOTS_CLI_PATHS_PROFILE",
- )),
- Some(RadrootsRuntimePathConfigEntry::new(
- "RADROOTS_CLI_PATHS_REPO_LOCAL_ROOT",
- "/repo/.local/radroots",
- "env_file:RADROOTS_CLI_PATHS_REPO_LOCAL_ROOT",
- )),
- RadrootsPathProfile::InteractiveUser,
- )
- .expect("config entries should select paths");
-
- assert_eq!(selection.profile, RadrootsPathProfile::RepoLocal);
- assert_eq!(
- selection.profile_source,
- "env_file:RADROOTS_CLI_PATHS_PROFILE"
- );
- assert_eq!(
- selection.repo_local_root,
- Some(PathBuf::from("/repo/.local/radroots"))
- );
- assert_eq!(
- selection.repo_local_root_source.as_deref(),
- Some("env_file:RADROOTS_CLI_PATHS_REPO_LOCAL_ROOT")
- );
- }
-
- #[test]
- fn config_entry_selection_uses_default_profile_without_sources() {
- let selection = RadrootsRuntimePathSelection::from_config_entries(
- None,
- None,
- RadrootsPathProfile::InteractiveUser,
- )
- .expect("default selection");
-
- assert_eq!(selection.profile, RadrootsPathProfile::InteractiveUser);
- assert_eq!(selection.profile_source, "default");
- assert_eq!(selection.repo_local_root, None);
- assert_eq!(selection.repo_local_root_source, None);
- }
-
- #[test]
- fn contract_captures_selection_sources() {
- let selection = RadrootsRuntimePathSelection::caller(
- RadrootsPathProfile::RepoLocal,
- Some(PathBuf::from("/repo/.local/radroots")),
- );
-
- let contract = selection.contract(
- &["interactive_user", "repo_local"],
- "config_artifact",
- &["config.service.logs_dir"],
- );
-
- assert_eq!(contract.active_profile, "repo_local");
- assert_eq!(
- contract.allowed_profiles,
- vec!["interactive_user".to_owned(), "repo_local".to_owned()]
- );
- assert_eq!(contract.path_overrides.profile_source, "caller");
- assert_eq!(
- contract.path_overrides.repo_local_root,
- Some(PathBuf::from("/repo/.local/radroots"))
- );
- }
-
- #[test]
- fn path_policy_contract_preserves_policy_strings() {
- let contract = RadrootsRuntimePathPolicyContract::new(
- "profile_root_env_or_repo_wrapper",
- "config_artifact",
- "runtime_owned_leaf_overrides",
- );
-
- assert_eq!(
- contract.canonical_root_selection,
- "profile_root_env_or_repo_wrapper"
- );
- assert_eq!(
- contract.leaf_path_env_posture,
- "runtime_owned_leaf_overrides"
- );
+ fn canonical_service_instance_suffix_uses_validated_ids() {
+ let roots = RadrootsPaths::from_base_root("/repo/.local/radroots");
+ let paths = RadrootsServiceInstancePaths::from_resolved_roots(
+ &roots,
+ &ServiceId::new("myc").expect("service"),
+ &InstanceId::new("primary").expect("instance"),
+ );
+ let suffix = PathBuf::from("services/myc/primary");
+
+ assert_eq!(paths.config(), roots.config.join(&suffix));
+ assert_eq!(paths.state(), roots.data.join(&suffix));
+ assert_eq!(paths.cache(), roots.cache.join(&suffix));
+ assert_eq!(paths.logs(), roots.logs.join(&suffix));
+ assert_eq!(paths.run(), roots.run.join(&suffix));
+ assert_eq!(paths.secrets(), roots.secrets.join(&suffix));
}
}
diff --git a/crates/runtime_paths/tests/package_boundary.rs b/crates/runtime_paths/tests/package_boundary.rs
@@ -0,0 +1,124 @@
+use std::collections::BTreeSet;
+
+const MANIFEST: &str = include_str!("../Cargo.toml");
+const README: &str = include_str!("../README");
+const PUBLIC_API: &str =
+ include_str!("../../../contracts/api_baselines/radroots_runtime_paths.txt");
+const ROOT: &str = include_str!("../src/lib.rs");
+const SOURCES: &[&str] = &[
+ include_str!("../src/context.rs"),
+ include_str!("../src/conventions.rs"),
+ include_str!("../src/error.rs"),
+ include_str!("../src/identifier.rs"),
+ include_str!("../src/platform.rs"),
+ include_str!("../src/roots.rs"),
+ include_str!("../src/service.rs"),
+];
+
+#[test]
+fn runtime_paths_is_unpublished_lint_governed_and_dependency_bounded() {
+ for required in [
+ "name = \"radroots_runtime_paths\"",
+ "publish = false",
+ "version = \"0.1.0-alpha\"",
+ ] {
+ assert!(
+ MANIFEST.contains(required),
+ "manifest is missing `{required}`"
+ );
+ }
+ assert_eq!(
+ dependency_keys(MANIFEST),
+ BTreeSet::from(["serde", "thiserror"])
+ );
+ assert!(!ROOT.contains("pub mod namespace;"));
+ for source in SOURCES {
+ let production = source.split("#[cfg(test)]").next().unwrap_or(source);
+ assert!(!production.contains("std::env"));
+ }
+}
+
+#[test]
+fn removed_namespace_selection_and_raw_root_surfaces_cannot_return() {
+ for forbidden in [
+ "RadrootsRuntimeNamespace",
+ "RadrootsRuntimeNamespaceKind",
+ "RadrootsServiceInstanceNamespace",
+ "RadrootsRuntimePathSelection",
+ "RadrootsRuntimePathConfigEntry",
+ "RadrootsRuntimePathPolicyContract",
+ "RadrootsRuntimeSelectionContract",
+ "RadrootsRuntimeSelectionOverrideContract",
+ "RadrootsPathOverrides",
+ "RadrootsBootstrapPaths",
+ "default_service_instance_paths",
+ "default_namespaced_bootstrap_paths",
+ "default_shared_identity_path",
+ "default_shared_runtime_logs_dir",
+ "from_current_process",
+ "MissingMobileRoots",
+ "InvalidNamespaceComponent",
+ ] {
+ assert!(
+ SOURCES.iter().all(|source| !source.contains(forbidden)) && !ROOT.contains(forbidden),
+ "removed runtime-path surface `{forbidden}` returned"
+ );
+ }
+
+ for forbidden in [
+ "pub struct radroots_runtime_paths::RadrootsPaths",
+ "pub struct radroots_runtime_paths::RadrootsPathOverrides",
+ "pub struct radroots_runtime_paths::RadrootsRuntimeNamespace",
+ "pub struct radroots_runtime_paths::RadrootsServiceInstanceNamespace",
+ "pub struct radroots_runtime_paths::RadrootsRuntimePathSelection",
+ "pub fn radroots_runtime_paths::RadrootsPathResolver::current",
+ "pub fn radroots_runtime_paths::RadrootsPathResolver::resolve",
+ ] {
+ assert!(
+ !PUBLIC_API.contains(forbidden),
+ "reviewed API baseline exposes `{forbidden}`"
+ );
+ }
+}
+
+#[test]
+fn reviewed_api_requires_the_typed_runtime_context_boundary() {
+ for required in [
+ "pub struct radroots_runtime_paths::RuntimeContext",
+ "pub struct radroots_runtime_paths::RuntimeContextBootstrap",
+ "pub enum radroots_runtime_paths::RuntimeContextSource",
+ "pub struct radroots_runtime_paths::RadrootsPathResolver",
+ "pub struct radroots_runtime_paths::RadrootsServiceInstancePaths",
+ "pub struct radroots_runtime_paths::RadrootsServiceInstanceArtifacts",
+ "pub struct radroots_runtime_paths::ServiceId",
+ "pub struct radroots_runtime_paths::InstanceId",
+ "pub fn radroots_runtime_paths::context::RuntimeContext::resolve",
+ ] {
+ assert!(
+ PUBLIC_API.contains(required),
+ "reviewed API baseline is missing `{required}`"
+ );
+ }
+
+ for required in [
+ "sole canonical",
+ "sealed `RuntimeContext`",
+ "process-environment constructor",
+ "intentionally removed",
+ ] {
+ assert!(README.contains(required), "README is missing `{required}`");
+ }
+}
+
+fn dependency_keys(manifest: &str) -> BTreeSet<&str> {
+ manifest
+ .split_once("[dependencies]")
+ .map(|(_, dependencies)| dependencies)
+ .unwrap_or_default()
+ .lines()
+ .skip(1)
+ .take_while(|line| !line.starts_with('['))
+ .filter_map(|line| line.split_once('=').map(|(key, _)| key.trim()))
+ .filter(|key| !key.is_empty())
+ .collect()
+}