use crate::meta::Meta;
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum Effect {
PathCreate { path: PathBuf },
File {
path: PathBuf,
prev_blob: String,
#[serde(default)]
meta: Meta,
},
Symlink { path: PathBuf, target: PathBuf },
Dir {
path: PathBuf,
#[serde(default)]
mode: u32,
entries: Vec<String>,
},
HttpMutation {
method: String,
url: String,
compensator: Option<HttpCompensator>,
},
Exec { command: String, cwd: PathBuf },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HttpCompensator {
pub method: String,
pub url: String,
pub body: Option<String>,
}
impl Effect {
pub fn reversible(&self) -> bool {
matches!(
self,
Effect::PathCreate { .. }
| Effect::File { .. }
| Effect::Symlink { .. }
| Effect::Dir { .. }
)
}
pub fn path(&self) -> Option<&Path> {
match self {
Effect::PathCreate { path }
| Effect::File { path, .. }
| Effect::Symlink { path, .. }
| Effect::Dir { path, .. } => Some(path),
_ => None,
}
}
pub fn describe(&self) -> String {
match self {
Effect::PathCreate { path } => format!("created {}", path.display()),
Effect::File { path, .. } => format!("captured {}", path.display()),
Effect::Symlink { path, .. } => format!("symlink {}", path.display()),
Effect::Dir { path, .. } => format!("dir {}", path.display()),
Effect::HttpMutation { method, url, .. } => format!("{method:<8} {url}"),
Effect::Exec { command, .. } => format!("ran {command}"),
}
}
}