use std::collections::BTreeMap;
use include_dir::{include_dir, Dir};
use serde::{Deserialize, Serialize};
use thiserror::Error;
static SCHEMAS_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/schemas/overrides");
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct OverrideSchema {
pub override_type: String,
pub schema_version: u32,
pub owner_crate: String,
pub phase: u8,
pub status: SchemaStatus,
#[serde(default)]
pub fields: BTreeMap<String, FieldSpec>,
#[serde(default)]
pub migration: BTreeMap<String, Vec<MigrationStep>>,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum SchemaStatus {
Stable,
Unstable,
Experimental,
Deprecated,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct FieldSpec {
#[serde(rename = "type")]
pub field_type: String,
#[serde(default)]
pub required: bool,
#[serde(default)]
pub default: Option<toml::Value>,
#[serde(default)]
pub max_len: Option<u32>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct MigrationStep {
pub op: String,
pub field: String,
#[serde(default)]
pub to: Option<String>,
#[serde(default)]
pub default: Option<toml::Value>,
}
pub fn lookup(override_type: &str, version: u32) -> Option<OverrideSchema> {
let path = format!("{override_type}-v{version}.toml");
let file = SCHEMAS_DIR.get_file(&path)?;
let content = file.contents_utf8()?;
toml::from_str(content).ok()
}
#[allow(unused_variables)]
pub fn validate_payload(
override_type: &str,
version: u32,
payload_toml: &str,
) -> Result<(), ValidationError> {
Ok(())
}
#[allow(unused_variables)]
pub fn migrate_payload(
override_type: &str,
from: u32,
to: u32,
payload_toml: &str,
) -> Result<String, MigrationError> {
Ok(payload_toml.to_string())
}
#[derive(Debug, Error)]
pub enum ValidationError {
#[error("champ inconnu : {0}")]
UnknownField(String),
#[error("champ obligatoire manquant : {0}")]
MissingRequired(String),
#[error("type incorrect pour le champ {0} : attendu {1}")]
TypeMismatch(String, String),
#[error("longueur max dépassée pour le champ {0} : obtenu {1}")]
MaxLenExceeded(String, u32),
}
#[derive(Debug, Error)]
pub enum MigrationError {
#[error("schéma introuvable : {0}-v{1}")]
SchemaNotFound(String, u32),
#[error("migration irréversible à l'étape {0}")]
Irreversible(String),
}