1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct ParseResult {
11 pub ledger: Option<Ledger>,
13 pub errors: Vec<Error>,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct Ledger {
20 pub directives: Vec<DirectiveJson>,
22 pub options: LedgerOptions,
24}
25
26#[derive(Debug, Clone, Default, Serialize, Deserialize)]
28pub struct LedgerOptions {
29 pub operating_currencies: Vec<String>,
31 pub title: Option<String>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
40#[serde(tag = "type")]
41#[allow(missing_docs)]
42pub enum DirectiveJson {
43 #[serde(rename = "transaction")]
45 Transaction {
46 date: String,
47 flag: String,
48 payee: Option<String>,
49 narration: Option<String>,
50 tags: Vec<String>,
51 links: Vec<String>,
52 postings: Vec<PostingJson>,
53 },
54 #[serde(rename = "balance")]
56 Balance {
57 date: String,
58 account: String,
59 amount: AmountValue,
60 },
61 #[serde(rename = "open")]
63 Open {
64 date: String,
65 account: String,
66 currencies: Vec<String>,
67 #[serde(skip_serializing_if = "Option::is_none")]
68 booking: Option<String>,
69 },
70 #[serde(rename = "close")]
72 Close { date: String, account: String },
73 #[serde(rename = "commodity")]
75 Commodity { date: String, currency: String },
76 #[serde(rename = "pad")]
78 Pad {
79 date: String,
80 account: String,
81 source_account: String,
82 },
83 #[serde(rename = "event")]
85 Event {
86 date: String,
87 event_type: String,
88 value: String,
89 },
90 #[serde(rename = "note")]
92 Note {
93 date: String,
94 account: String,
95 comment: String,
96 },
97 #[serde(rename = "document")]
99 Document {
100 date: String,
101 account: String,
102 path: String,
103 },
104 #[serde(rename = "price")]
106 Price {
107 date: String,
108 currency: String,
109 amount: AmountValue,
110 },
111 #[serde(rename = "query")]
113 Query {
114 date: String,
115 name: String,
116 query_string: String,
117 },
118 #[serde(rename = "custom")]
120 Custom { date: String, custom_type: String },
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct PostingJson {
126 pub account: String,
128 #[serde(skip_serializing_if = "Option::is_none")]
130 pub units: Option<AmountValue>,
131 #[serde(skip_serializing_if = "Option::is_none")]
133 pub cost: Option<PostingCostJson>,
134 #[serde(skip_serializing_if = "Option::is_none")]
136 pub price: Option<AmountValue>,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
141pub struct PostingCostJson {
142 #[serde(skip_serializing_if = "Option::is_none")]
144 pub number_per: Option<String>,
145 #[serde(skip_serializing_if = "Option::is_none")]
147 pub currency: Option<String>,
148 #[serde(skip_serializing_if = "Option::is_none")]
150 pub date: Option<String>,
151 #[serde(skip_serializing_if = "Option::is_none")]
153 pub label: Option<String>,
154}
155
156#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
158#[serde(rename_all = "lowercase")]
159pub enum Severity {
160 Error,
162 Warning,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct Error {
169 pub message: String,
171 pub line: Option<u32>,
173 pub column: Option<u32>,
175 pub severity: Severity,
177}
178
179impl Error {
180 pub fn new(message: impl Into<String>) -> Self {
182 Self {
183 message: message.into(),
184 line: None,
185 column: None,
186 severity: Severity::Error,
187 }
188 }
189
190 pub fn with_line(message: impl Into<String>, line: u32) -> Self {
192 Self {
193 message: message.into(),
194 line: Some(line),
195 column: None,
196 severity: Severity::Error,
197 }
198 }
199
200 pub fn warning(message: impl Into<String>) -> Self {
202 Self {
203 message: message.into(),
204 line: None,
205 column: None,
206 severity: Severity::Warning,
207 }
208 }
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct ValidationResult {
214 pub valid: bool,
216 pub errors: Vec<Error>,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct QueryResult {
223 pub columns: Vec<String>,
225 pub rows: Vec<Vec<CellValue>>,
227 pub errors: Vec<Error>,
229}
230
231#[derive(Debug, Clone, Serialize, Deserialize)]
235#[serde(untagged)]
236#[allow(missing_docs)]
237pub enum CellValue {
238 Null,
240 String(String),
242 Integer(i64),
244 Boolean(bool),
246 Amount { number: String, currency: String },
248 Position {
250 units: AmountValue,
251 #[serde(skip_serializing_if = "Option::is_none")]
252 cost: Option<CostValue>,
253 },
254 Inventory { positions: Vec<PositionValue> },
256 StringSet(Vec<String>),
258 Object(std::collections::HashMap<String, Box<Self>>),
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
264pub struct AmountValue {
265 pub number: String,
267 pub currency: String,
269}
270
271#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct PositionValue {
274 pub units: AmountValue,
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize)]
280pub struct CostValue {
281 pub number: String,
283 pub currency: String,
285 #[serde(skip_serializing_if = "Option::is_none")]
287 pub date: Option<String>,
288 #[serde(skip_serializing_if = "Option::is_none")]
290 pub label: Option<String>,
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize)]
295pub struct FormatResult {
296 pub formatted: Option<String>,
298 pub errors: Vec<Error>,
300}
301
302#[derive(Debug, Clone, Serialize, Deserialize)]
304pub struct PadResult {
305 pub directives: Vec<DirectiveJson>,
307 pub padding_transactions: Vec<DirectiveJson>,
309 pub errors: Vec<Error>,
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize)]
315pub struct PluginResult {
316 pub directives: Vec<DirectiveJson>,
318 pub errors: Vec<Error>,
320}
321
322#[derive(Debug, Clone, Serialize, Deserialize)]
324pub struct PluginInfo {
325 pub name: String,
327 pub description: String,
329}
330
331#[derive(Debug, Clone, Serialize, Deserialize)]
333pub struct CompletionJson {
334 pub text: String,
336 pub category: String,
338 #[serde(skip_serializing_if = "Option::is_none")]
340 pub description: Option<String>,
341}
342
343#[derive(Debug, Clone, Serialize, Deserialize)]
345pub struct CompletionResultJson {
346 pub completions: Vec<CompletionJson>,
348 pub context: String,
350}
351
352#[derive(Debug, Clone, Serialize, Deserialize)]
358pub struct EditorCompletion {
359 pub label: String,
361 pub kind: CompletionKind,
363 #[serde(skip_serializing_if = "Option::is_none")]
365 pub detail: Option<String>,
366 #[serde(skip_serializing_if = "Option::is_none")]
368 pub insert_text: Option<String>,
369}
370
371#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
373#[serde(rename_all = "lowercase")]
374pub enum CompletionKind {
375 Keyword,
377 Account,
379 AccountSegment,
381 Currency,
383 Payee,
385 Date,
387 Text,
389}
390
391#[derive(Debug, Clone, Serialize, Deserialize)]
393pub struct EditorCompletionResult {
394 pub completions: Vec<EditorCompletion>,
396 pub context: String,
398}
399
400#[derive(Debug, Clone, Serialize, Deserialize)]
402pub struct EditorHoverInfo {
403 pub contents: String,
405 #[serde(skip_serializing_if = "Option::is_none")]
407 pub range: Option<EditorRange>,
408}
409
410#[derive(Debug, Clone, Serialize, Deserialize)]
412pub struct EditorRange {
413 pub start_line: u32,
415 pub start_character: u32,
417 pub end_line: u32,
419 pub end_character: u32,
421}
422
423#[derive(Debug, Clone, Serialize, Deserialize)]
425pub struct EditorLocation {
426 pub line: u32,
428 pub character: u32,
430}
431
432#[derive(Debug, Clone, Serialize, Deserialize)]
434pub struct EditorDocumentSymbol {
435 pub name: String,
437 #[serde(skip_serializing_if = "Option::is_none")]
439 pub detail: Option<String>,
440 pub kind: SymbolKind,
442 pub range: EditorRange,
444 #[serde(skip_serializing_if = "Option::is_none")]
446 pub children: Option<Vec<Self>>,
447 #[serde(skip_serializing_if = "Option::is_none")]
449 pub deprecated: Option<bool>,
450}
451
452#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
454#[serde(rename_all = "lowercase")]
455pub enum SymbolKind {
456 Transaction,
458 Account,
460 Balance,
462 Commodity,
464 Posting,
466 Pad,
468 Event,
470 Note,
472 Document,
474 Price,
476 Query,
478 Custom,
480}
481
482#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
488#[serde(rename_all = "lowercase")]
489pub enum ReferenceKind {
490 Account,
492 Currency,
494 Payee,
496}
497
498#[derive(Debug, Clone, Serialize, Deserialize)]
500pub struct EditorReference {
501 pub range: EditorRange,
503 pub kind: ReferenceKind,
505 pub is_definition: bool,
507 #[serde(skip_serializing_if = "Option::is_none")]
509 pub context: Option<String>,
510}
511
512#[derive(Debug, Clone, Serialize, Deserialize)]
514pub struct EditorReferencesResult {
515 pub symbol: String,
517 pub kind: ReferenceKind,
519 pub references: Vec<EditorReference>,
521}