use std::path::{Path, PathBuf};
use agent_migrate_core::{AgentKind, BundleRelativePath, FileKind, Scope};
use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum ResourceClass {
Migratable,
MetadataOnly,
Excluded,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct ResourceEntry {
pub logical_path: String,
pub class: ResourceClass,
pub kind: Option<FileKind>,
pub reason: String,
pub bundle_path: Option<BundleRelativePath>,
#[serde(skip)]
source_path: Option<PathBuf>,
}
#[derive(Debug)]
pub(crate) struct MigratableLocation {
pub logical: String,
pub source: PathBuf,
pub bundle: BundleRelativePath,
}
impl ResourceEntry {
#[must_use]
pub(crate) fn migratable(location: MigratableLocation, kind: FileKind) -> Self {
Self {
logical_path: location.logical,
class: ResourceClass::Migratable,
kind: Some(kind),
reason: "supported adapter resource".to_owned(),
bundle_path: Some(location.bundle),
source_path: Some(location.source),
}
}
#[must_use]
pub(crate) fn protected(class: ResourceClass, index: usize, reason: &str) -> Self {
Self {
logical_path: format!("<redacted:{index}>"),
class,
kind: None,
reason: reason.to_owned(),
bundle_path: None,
source_path: None,
}
}
#[must_use]
pub(crate) fn source_path(&self) -> Option<&Path> {
self.source_path.as_deref()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct Inventory {
pub agent: AgentKind,
pub scope: Scope,
pub entries: Vec<ResourceEntry>,
}
impl Inventory {
#[must_use]
pub const fn new(agent: AgentKind, scope: Scope, entries: Vec<ResourceEntry>) -> Self {
Self {
agent,
scope,
entries,
}
}
#[must_use]
pub fn count(&self, class: ResourceClass) -> usize {
self.entries
.iter()
.filter(|entry| entry.class == class)
.count()
}
}