use acorn_core::prelude::{String, Vec};
use acorn_core::util::{MarkdownSupport, MimeType};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize, strum::EnumIs)]
#[serde(rename_all = "kebab-case")]
pub enum FileChangeKind {
Create,
Update,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize, strum::Display, strum::EnumIs)]
#[serde(rename_all = "kebab-case")]
#[strum(serialize_all = "kebab-case")]
pub enum WorkflowAction {
Check,
Enrich,
Format,
Link,
Validate,
}
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct FileChange {
pub content: String,
pub kind: FileChangeKind,
pub path: String,
}
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct RepositoryChangeSet {
pub base_revision: String,
pub files: Vec<FileChange>,
pub reports: Vec<WorkflowFileReport>,
}
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct RepositoryFileInput {
pub path: String,
pub content: String,
pub format: Option<MimeType>,
}
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct RepositoryInput {
pub actions: Vec<WorkflowAction>,
pub files: Vec<RepositoryFileInput>,
pub project: String,
pub revision: String,
}
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct WorkflowFileReport {
pub changed: bool,
pub format: MimeType,
pub path: String,
}
impl MarkdownSupport for RepositoryChangeSet {
fn to_markdown(&self) -> String {
self.files
.iter()
.map(|change| {
let kind: &'static str = change.kind.into();
format!("- `{}` ({kind})", change.path)
})
.collect::<Vec<_>>()
.join("\n")
}
}
impl RepositoryFileInput {
pub fn format(&self) -> Option<MimeType> {
let format = self.format.clone().unwrap_or_else(|| MimeType::from(self.path.as_str()));
match format {
| MimeType::Cff | MimeType::Json | MimeType::Jsonc | MimeType::Markdown | MimeType::Yaml | MimeType::Zon => Some(format),
| _ => None,
}
}
}
impl From<FileChangeKind> for &'static str {
fn from(value: FileChangeKind) -> Self {
match value {
| FileChangeKind::Create => "create",
| FileChangeKind::Update => "update",
}
}
}