use crate::id::Uid;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(try_from = "ValueRepr", into = "ValueRepr")]
pub enum Value {
Text(String),
Number(f64),
Json(serde_json::Value),
}
#[derive(Serialize, Deserialize)]
enum ValueRepr {
Text(String),
Number(f64),
Json(String),
}
impl From<Value> for ValueRepr {
fn from(v: Value) -> Self {
match v {
Value::Text(s) => ValueRepr::Text(s),
Value::Number(n) => ValueRepr::Number(n),
Value::Json(j) => ValueRepr::Json(j.to_string()),
}
}
}
impl TryFrom<ValueRepr> for Value {
type Error = String;
fn try_from(r: ValueRepr) -> Result<Self, Self::Error> {
Ok(match r {
ValueRepr::Text(s) => Value::Text(s),
ValueRepr::Number(n) => Value::Number(n),
ValueRepr::Json(s) => Value::Json(serde_json::from_str(&s).map_err(|e| e.to_string())?),
})
}
}
impl Value {
pub fn kind(&self) -> ValueKind {
match self {
Value::Text(_) => ValueKind::Text,
Value::Number(_) => ValueKind::Number,
Value::Json(_) => ValueKind::Json,
}
}
pub fn canonical_bytes(&self) -> Vec<u8> {
match self {
Value::Text(s) => s.as_bytes().to_vec(),
Value::Number(n) => format!("{n}").into_bytes(),
Value::Json(v) => v.to_string().into_bytes(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ValueKind {
Text,
Number,
Json,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum StoredValue {
Plain(Value),
Sha256(String),
Hmac {
key_version: u32,
digest: String,
},
Rsa {
key_version: u32,
wrapped_key: String,
nonce: String,
ciphertext: String,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(try_from = "ContentRepr", into = "ContentRepr")]
pub enum Content {
Text(String),
Json(serde_json::Value),
}
#[derive(Serialize, Deserialize)]
enum ContentRepr {
Text(String),
Json(String),
}
impl From<Content> for ContentRepr {
fn from(c: Content) -> Self {
match c {
Content::Text(s) => ContentRepr::Text(s),
Content::Json(j) => ContentRepr::Json(j.to_string()),
}
}
}
impl TryFrom<ContentRepr> for Content {
type Error = String;
fn try_from(r: ContentRepr) -> Result<Self, Self::Error> {
Ok(match r {
ContentRepr::Text(s) => Content::Text(s),
ContentRepr::Json(s) => {
Content::Json(serde_json::from_str(&s).map_err(|e| e.to_string())?)
}
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditLog {
pub log_id: Uid,
pub timestamp: u64,
pub actor: Uid,
pub actor_type: String,
pub method: String,
pub url: String,
pub content: Content,
pub custom: BTreeMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TargetRelation {
pub log_id: Uid,
pub entity_registry_uid: Uid,
pub entity_type: String,
}