use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::author::{AuthorStamp, UserId};
use crate::evidence::EvidenceId;
use crate::ids::{ProjectId, TenantId, VertexId};
use crate::observation::ObservationId;
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(transparent)]
pub struct BeliefId(pub String);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Belief {
pub id: BeliefId,
pub tenant_id: TenantId,
pub project_id: ProjectId,
pub subject_id: VertexId,
pub predicate: String,
pub value_json: Value,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub confidence: Option<f32>,
pub belief_version: u64,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub derived_from: Vec<ObservationId>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub evidence_ids: Vec<EvidenceId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub valid_from: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub valid_to: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub observed_at: Option<DateTime<Utc>>,
pub updated_at: DateTime<Utc>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub decay_policy: Option<String>,
#[serde(default, skip_serializing_if = "Value::is_null")]
pub metadata: Value,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub author: Option<AuthorStamp>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub contributing_authors: Vec<UserId>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct BeliefContent {
pub value_json: String,
pub confidence_bits: Option<u32>,
pub derived_from: Vec<ObservationId>,
pub evidence_ids: Vec<EvidenceId>,
pub valid_from: Option<DateTime<Utc>>,
pub valid_to: Option<DateTime<Utc>>,
pub observed_at: Option<DateTime<Utc>>,
pub decay_policy: Option<String>,
pub metadata: String,
}
impl Belief {
pub fn content_fingerprint(&self) -> BeliefContent {
BeliefContent {
value_json: self.value_json.to_string(),
confidence_bits: self.confidence.map(f32::to_bits),
derived_from: {
let mut v = self.derived_from.clone();
v.sort();
v
},
evidence_ids: {
let mut v = self.evidence_ids.clone();
v.sort();
v
},
valid_from: self.valid_from,
valid_to: self.valid_to,
observed_at: self.observed_at,
decay_policy: self.decay_policy.clone(),
metadata: self.metadata.to_string(),
}
}
}