use serde::{Deserialize, Serialize};
use super::graph::Triple;
use super::ioc::Ioc;
use super::proposition::Proposition;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Document {
pub id: String,
pub text: String,
#[serde(default)]
pub sections: Vec<Section>,
}
impl Document {
pub fn new(id: impl Into<String>, text: impl Into<String>) -> Self {
Self {
id: id.into(),
text: text.into(),
sections: Vec::new(),
}
}
pub fn with_sections(mut self, sections: Vec<Section>) -> Self {
self.sections = sections;
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Section {
pub kind: SectionKind,
pub text: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "snake_case")]
pub enum SectionKind {
Narrative,
Table,
Code,
Other,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct IngestionDelta {
pub iocs: Vec<Ioc>,
pub propositions: Vec<Proposition>,
pub triples: Vec<Triple>,
pub dropped: Vec<Dropped>,
#[serde(default)]
pub knowledge_gain: f64,
}
impl IngestionDelta {
pub fn new() -> Self {
Self::default()
}
pub fn is_empty(&self) -> bool {
self.iocs.is_empty() && self.propositions.is_empty() && self.triples.is_empty()
}
#[must_use]
pub fn with_knowledge_gain(mut self, knowledge_gain: f64) -> Self {
self.knowledge_gain = knowledge_gain.clamp(0.0, 1.0);
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Dropped {
pub item: DroppedItem,
pub reason: DroppedReason,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum DroppedItem {
Ioc(Ioc),
Proposition(Proposition),
Triple(Triple),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum DroppedReason {
DuplicateIoc,
Redundant {
similarity: f64,
},
DuplicateEdge,
}