pub struct ProfileStore {
path: PathBuf,
manual: Vec<Profile>,
discovered_validated_at: HashMap<ProfileId, i64>,
}Expand description
Aggregate profile store.
Holds manual profiles in memory (loaded from and persisted to
${app_config_dir}/profiles.json). AWS-discovered and env profiles are
re-read from their sources on every list call.
Fields§
§path: PathBufPath to profiles.json.
manual: Vec<Profile>In-memory set of manual profiles.
discovered_validated_at: HashMap<ProfileId, i64>Session-scoped validated_at cache for AWS-discovered / env profiles.
These profiles are re-read from ~/.aws/* on every list() call so
any validated_at we mark on the in-memory representation would be
dropped on the next call. Persisting it to disk is wrong (the user’s
~/.aws/config is theirs and we shouldn’t write to it), so the
cache lives here, in memory, for the lifetime of the session and is
merged into the freshly-rebuilt profiles by list().
Without this, the validation gate (useValidatedProfile) blocks
every action on a discovered profile because its validated_at
stays None even after a successful profile_validate.
Implementations§
Source§impl ProfileStore
impl ProfileStore
Sourcepub fn empty(path: PathBuf) -> Self
pub fn empty(path: PathBuf) -> Self
Construct an empty ProfileStore backed by path, without touching
disk. Used as the last-resort fallback when both the primary and
temp-dir profiles.json paths are unreadable — the user starts the
session with no manual profiles but the app at least opens.
Sourcepub fn load(path: impl Into<PathBuf>) -> Result<Self, AppError>
pub fn load(path: impl Into<PathBuf>) -> Result<Self, AppError>
Create a new ProfileStore backed by path.
Loads existing manual profiles from disk if the file exists; starts empty otherwise. Never errors on a missing file.
fn read_from_disk(path: &Path) -> Result<Vec<Profile>, AppError>
Sourcefn flush(&self) -> Result<(), AppError>
fn flush(&self) -> Result<(), AppError>
Persist the current manual profiles to disk atomically.
Sourcefn discovered_id(source: &ProfileSource, display_name: &str) -> ProfileId
fn discovered_id(source: &ProfileSource, display_name: &str) -> ProfileId
Derive a stable, deterministic ProfileId for a discovered profile.
Uses a synthetic "aws-discovered:<source_tag>:<display_name>" ID so
the value is stable across restarts without needing persistence.
Collisions with manually-minted UUID v4 IDs are cosmetically impossible.
Sourcepub fn list(&self) -> Vec<Profile>
pub fn list(&self) -> Vec<Profile>
Return the aggregated list of all profiles.
Aggregation order:
- AWS-discovered profiles (read from
~/.aws/*synchronously). - Env-derived synthetic profile (when env vars are present).
- Manual profiles (from in-memory store, loaded from disk).
Dedup key: (source, display_name). Manual profiles always win, so
they are processed last and overwrite any same-key discovered entry.
Sourcepub fn get(&self, id: &ProfileId) -> Option<Profile>
pub fn get(&self, id: &ProfileId) -> Option<Profile>
Return the profile with the given id, or None if not found.
Sourcepub fn create_manual(
&mut self,
name: String,
secret: Secret,
default_region: Option<String>,
compat_flags: Option<CompatFlags>,
keychain: &mut dyn KeychainBackend,
) -> Result<Profile, AppError>
pub fn create_manual( &mut self, name: String, secret: Secret, default_region: Option<String>, compat_flags: Option<CompatFlags>, keychain: &mut dyn KeychainBackend, ) -> Result<Profile, AppError>
Create a new manual profile.
- Mints a stable UUID v4 for the new profile.
- Persists the secret to the keychain via
keychain. - Persists profile metadata to disk.
access_key_id and name must be non-empty; returns
AppError::Validation otherwise.
Sourcepub fn update(
&mut self,
id: &ProfileId,
patch: ProfileUpdatePatch,
) -> Result<Profile, AppError>
pub fn update( &mut self, id: &ProfileId, patch: ProfileUpdatePatch, ) -> Result<Profile, AppError>
Update a manual profile’s name and/or compat flags.
Only display_name, compat_flags, and default_region may be patched.
Returns AppError::NotFound if the profile does not exist or is not a
manual profile.
Sourcepub fn delete(
&mut self,
id: &ProfileId,
keychain: &mut dyn KeychainBackend,
) -> Result<(), AppError>
pub fn delete( &mut self, id: &ProfileId, keychain: &mut dyn KeychainBackend, ) -> Result<(), AppError>
Delete a manual profile by id.
Also removes the associated keychain entry. Returns AppError::NotFound
if the profile does not exist in the manual set.
Sourcepub fn mark_validated(&mut self, id: &ProfileId, ts: i64)
pub fn mark_validated(&mut self, id: &ProfileId, ts: i64)
Mark a profile as validated at the given Unix-millisecond timestamp.
For manual profiles the timestamp is persisted to profiles.json.
For discovered/env profiles it is recorded in the session-scoped
discovered_validated_at map and merged back into the freshly
rebuilt profiles on every list call. Persisting
discovered timestamps to disk would mean writing to the user’s
~/.aws/* files, which we deliberately do not do.
Auto Trait Implementations§
impl Freeze for ProfileStore
impl RefUnwindSafe for ProfileStore
impl Send for ProfileStore
impl Sync for ProfileStore
impl Unpin for ProfileStore
impl UnsafeUnpin for ProfileStore
impl UnwindSafe for ProfileStore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more