Skip to main content

mempal_runtime/aaak/
model.rs

1use std::fmt::{Display, Formatter};
2
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6use super::parse::parse_document;
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub struct AaakMeta {
10    pub wing: String,
11    pub room: String,
12    pub date: String,
13    pub source: String,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub struct AaakHeader {
18    pub version: u8,
19    pub wing: String,
20    pub room: String,
21    pub date: String,
22    pub source: String,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
26pub struct Zettel {
27    pub id: usize,
28    pub entities: Vec<String>,
29    pub topics: Vec<String>,
30    pub quote: String,
31    pub weight: u8,
32    pub emotions: Vec<String>,
33    pub flags: Vec<String>,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
37pub struct Tunnel {
38    pub left: usize,
39    pub right: usize,
40    pub label: String,
41}
42
43#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
44pub struct ArcLine {
45    pub emotions: Vec<String>,
46}
47
48#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
49pub enum AaakLine {
50    Zettel(Zettel),
51    Tunnel(Tunnel),
52    Arc(ArcLine),
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
56pub struct AaakDocument {
57    pub header: AaakHeader,
58    pub body: Vec<AaakLine>,
59    pub zettels: Vec<Zettel>,
60}
61
62impl AaakDocument {
63    pub fn parse(input: &str) -> Result<Self, ParseError> {
64        parse_document(input)
65    }
66
67    pub fn zettel_lines(&self) -> Vec<Zettel> {
68        if !self.body.is_empty() {
69            return self
70                .body
71                .iter()
72                .filter_map(|line| match line {
73                    AaakLine::Zettel(zettel) => Some(zettel.clone()),
74                    AaakLine::Tunnel(_) | AaakLine::Arc(_) => None,
75                })
76                .collect();
77        }
78
79        self.zettels.clone()
80    }
81}
82
83impl Display for AaakDocument {
84    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
85        writeln!(
86            f,
87            "V{}|{}|{}|{}|{}",
88            self.header.version,
89            self.header.wing,
90            self.header.room,
91            self.header.date,
92            self.header.source
93        )?;
94
95        for (index, line) in self.body_lines().iter().enumerate() {
96            if index > 0 {
97                writeln!(f)?;
98            }
99            match line {
100                AaakLine::Zettel(zettel) => write!(
101                    f,
102                    "{}:{}|{}|\"{}\"|{}|{}|{}",
103                    zettel.id,
104                    zettel.entities.join("+"),
105                    zettel.topics.join("_"),
106                    zettel.quote.replace('"', "'"),
107                    "★".repeat(usize::from(zettel.weight.max(1))),
108                    zettel.emotions.join("+"),
109                    zettel.flags.join("+"),
110                )?,
111                AaakLine::Tunnel(tunnel) => {
112                    write!(f, "T:{}<->{}|{}", tunnel.left, tunnel.right, tunnel.label)?
113                }
114                AaakLine::Arc(arc) => write!(f, "ARC:{}", arc.emotions.join("->"))?,
115            }
116        }
117
118        Ok(())
119    }
120}
121
122impl AaakDocument {
123    fn body_lines(&self) -> Vec<AaakLine> {
124        if !self.body.is_empty() {
125            return self.body.clone();
126        }
127
128        self.zettels.iter().cloned().map(AaakLine::Zettel).collect()
129    }
130}
131
132#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
133pub struct EncodeReport {
134    pub topics_truncated: usize,
135    pub key_sentence_truncated: bool,
136    pub coverage: f32,
137    pub lost_assertions: Vec<String>,
138}
139
140#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
141pub struct EncodeOutput {
142    pub document: AaakDocument,
143    pub report: EncodeReport,
144}
145
146#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
147pub struct RoundtripReport {
148    pub preserved: Vec<String>,
149    pub lost: Vec<String>,
150    pub coverage: f32,
151}
152
153#[derive(Debug, Error, PartialEq, Eq)]
154pub enum ParseError {
155    #[error("missing AAAK header")]
156    MissingHeader,
157    #[error("invalid AAAK header")]
158    InvalidHeader,
159    #[error("invalid version marker")]
160    InvalidVersion,
161    #[error("invalid zettel line: {0}")]
162    InvalidZettel(String),
163}