1use rkyv::{Archive, Deserialize, Serialize};
7
8#[derive(Archive, Serialize, Deserialize, Debug, Clone, PartialEq)]
10#[rkyv(derive(Debug))]
11pub struct MachineDocument {
12 pub context: Vec<(String, usize)>,
14 pub refs: Vec<(String, String)>,
16 pub sections: Vec<(char, MachineSection)>,
18 pub section_names: Vec<(char, String)>,
20 pub entry_order: Vec<MachineEntryRef>,
22 pub value_arena: Vec<MachineValue>,
24}
25
26#[derive(Archive, Serialize, Deserialize, Debug, Clone, PartialEq)]
28#[rkyv(derive(Debug))]
29pub enum MachineEntryRef {
30 Context(String),
32 Section(char),
34}
35
36#[derive(Archive, Serialize, Deserialize, Debug, Clone, PartialEq)]
38#[rkyv(derive(Debug))]
39pub struct MachineSection {
40 pub schema: Vec<String>,
42 pub rows: Vec<Vec<usize>>,
44}
45
46#[derive(Archive, Serialize, Deserialize, Debug, Clone, PartialEq)]
48#[rkyv(derive(Debug))]
49pub enum MachineValue {
50 Str(String),
52 Num(f64),
54 Bool(bool),
56 Null,
58 Arr(Vec<usize>),
60 Obj(Vec<(String, usize)>),
62 Ref(String),
64}
65
66impl From<&crate::llm::types::DxDocument> for MachineDocument {
67 fn from(doc: &crate::llm::types::DxDocument) -> Self {
68 use crate::llm::types::EntryRef;
69
70 let mut value_arena = Vec::new();
71 let mut context = Vec::new();
72
73 for (k, v) in &doc.context {
75 let idx = add_value_to_arena(v, &mut value_arena);
76 context.push((k.clone(), idx));
77 }
78
79 let sections: Vec<(char, MachineSection)> = doc
81 .sections
82 .iter()
83 .map(|(k, v)| {
84 let schema = v.schema.clone();
85 let rows: Vec<Vec<usize>> = v
86 .rows
87 .iter()
88 .map(|row| {
89 row.iter()
90 .map(|cell| add_value_to_arena(cell, &mut value_arena))
91 .collect()
92 })
93 .collect();
94 (*k, MachineSection { schema, rows })
95 })
96 .collect();
97
98 Self {
99 context,
100 refs: doc
101 .refs
102 .iter()
103 .map(|(k, v)| (k.clone(), v.clone()))
104 .collect(),
105 sections,
106 section_names: doc
107 .section_names
108 .iter()
109 .map(|(k, v)| (*k, v.clone()))
110 .collect(),
111 entry_order: doc
112 .entry_order
113 .iter()
114 .map(|e| match e {
115 EntryRef::Context(s) => MachineEntryRef::Context(s.clone()),
116 EntryRef::Section(c) => MachineEntryRef::Section(*c),
117 })
118 .collect(),
119 value_arena,
120 }
121 }
122}
123
124fn add_value_to_arena(v: &crate::llm::types::DxLlmValue, arena: &mut Vec<MachineValue>) -> usize {
125 use crate::llm::types::DxLlmValue;
126
127 let idx = arena.len();
128 arena.push(MachineValue::Null);
129 let machine_value = match v {
130 DxLlmValue::Str(s) => MachineValue::Str(s.clone()),
131 DxLlmValue::Num(n) => MachineValue::Num(*n),
132 DxLlmValue::Bool(b) => MachineValue::Bool(*b),
133 DxLlmValue::Null => MachineValue::Null,
134 DxLlmValue::Arr(items) => {
135 let indices: Vec<usize> = items
136 .iter()
137 .map(|item| add_value_to_arena(item, arena))
138 .collect();
139 MachineValue::Arr(indices)
140 }
141 DxLlmValue::Obj(fields) => {
142 let pairs: Vec<(String, usize)> = fields
143 .iter()
144 .map(|(k, v)| (k.clone(), add_value_to_arena(v, arena)))
145 .collect();
146 MachineValue::Obj(pairs)
147 }
148 DxLlmValue::Ref(r) => MachineValue::Ref(r.clone()),
149 };
150 arena[idx] = machine_value;
151 idx
152}
153
154impl From<&MachineDocument> for crate::llm::types::DxDocument {
155 fn from(m: &MachineDocument) -> Self {
156 use crate::llm::types::{DxDocument, DxSection, EntryRef};
157
158 let mut doc = DxDocument::new();
159
160 for (k, idx) in &m.context {
162 let value = get_value_from_arena(*idx, &m.value_arena);
163 doc.context.insert(k.clone(), value);
164 }
165
166 doc.refs = m.refs.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
167
168 for (k, section) in &m.sections {
170 let mut dx_section = DxSection::new(section.schema.clone());
171 for row_indices in §ion.rows {
172 let row: Vec<_> = row_indices
173 .iter()
174 .map(|idx| get_value_from_arena(*idx, &m.value_arena))
175 .collect();
176 dx_section.rows.push(row);
177 }
178 doc.sections.insert(*k, dx_section);
179 }
180
181 doc.section_names = m
182 .section_names
183 .iter()
184 .map(|(k, v)| (*k, v.clone()))
185 .collect();
186 doc.entry_order = m
187 .entry_order
188 .iter()
189 .map(|e| match e {
190 MachineEntryRef::Context(s) => EntryRef::Context(s.clone()),
191 MachineEntryRef::Section(c) => EntryRef::Section(*c),
192 })
193 .collect();
194 doc
195 }
196}
197
198fn get_value_from_arena(idx: usize, arena: &[MachineValue]) -> crate::llm::types::DxLlmValue {
199 use crate::llm::types::DxLlmValue;
200 use indexmap::IndexMap;
201
202 match &arena[idx] {
203 MachineValue::Str(s) => DxLlmValue::Str(s.clone()),
204 MachineValue::Num(n) => DxLlmValue::Num(*n),
205 MachineValue::Bool(b) => DxLlmValue::Bool(*b),
206 MachineValue::Null => DxLlmValue::Null,
207 MachineValue::Arr(indices) => {
208 let items: Vec<DxLlmValue> = indices
209 .iter()
210 .map(|i| get_value_from_arena(*i, arena))
211 .collect();
212 DxLlmValue::Arr(items)
213 }
214 MachineValue::Obj(pairs) => {
215 let mut fields = IndexMap::new();
216 for (k, i) in pairs {
217 fields.insert(k.clone(), get_value_from_arena(*i, arena));
218 }
219 DxLlmValue::Obj(fields)
220 }
221 MachineValue::Ref(r) => DxLlmValue::Ref(r.clone()),
222 }
223}