1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct PluginInput {
11 pub directives: Vec<DirectiveWrapper>,
13 pub options: PluginOptions,
15 pub config: Option<String>,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct PluginOutput {
22 pub directives: Vec<DirectiveWrapper>,
24 pub errors: Vec<PluginError>,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct DirectiveWrapper {
34 #[serde(skip_serializing, default)]
36 pub directive_type: String,
37 pub date: String,
39 #[serde(flatten)]
41 pub data: DirectiveData,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
46#[serde(tag = "type")]
47pub enum DirectiveData {
48 #[serde(rename = "transaction")]
50 Transaction(TransactionData),
51 #[serde(rename = "balance")]
53 Balance(BalanceData),
54 #[serde(rename = "open")]
56 Open(OpenData),
57 #[serde(rename = "close")]
59 Close(CloseData),
60 #[serde(rename = "commodity")]
62 Commodity(CommodityData),
63 #[serde(rename = "pad")]
65 Pad(PadData),
66 #[serde(rename = "event")]
68 Event(EventData),
69 #[serde(rename = "note")]
71 Note(NoteData),
72 #[serde(rename = "document")]
74 Document(DocumentData),
75 #[serde(rename = "price")]
77 Price(PriceData),
78 #[serde(rename = "query")]
80 Query(QueryData),
81 #[serde(rename = "custom")]
83 Custom(CustomData),
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct TransactionData {
89 pub flag: String,
91 pub payee: Option<String>,
93 pub narration: String,
95 pub tags: Vec<String>,
97 pub links: Vec<String>,
99 pub metadata: Vec<(String, MetaValueData)>,
101 pub postings: Vec<PostingData>,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct PostingData {
108 pub account: String,
110 pub units: Option<AmountData>,
112 pub cost: Option<CostData>,
114 pub price: Option<PriceAnnotationData>,
116 pub flag: Option<String>,
118 pub metadata: Vec<(String, MetaValueData)>,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct AmountData {
125 pub number: String,
127 pub currency: String,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct CostData {
134 pub number_per: Option<String>,
136 pub number_total: Option<String>,
138 pub currency: Option<String>,
140 pub date: Option<String>,
142 pub label: Option<String>,
144 pub merge: bool,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct PriceAnnotationData {
151 pub is_total: bool,
153 pub amount: Option<AmountData>,
155 pub number: Option<String>,
157 pub currency: Option<String>,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
163#[serde(tag = "type", content = "value")]
164pub enum MetaValueData {
165 #[serde(rename = "string")]
167 String(String),
168 #[serde(rename = "number")]
170 Number(String),
171 #[serde(rename = "date")]
173 Date(String),
174 #[serde(rename = "account")]
176 Account(String),
177 #[serde(rename = "currency")]
179 Currency(String),
180 #[serde(rename = "tag")]
182 Tag(String),
183 #[serde(rename = "link")]
185 Link(String),
186 #[serde(rename = "amount")]
188 Amount(AmountData),
189 #[serde(rename = "bool")]
191 Bool(bool),
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct BalanceData {
197 pub account: String,
199 pub amount: AmountData,
201 pub tolerance: Option<String>,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct OpenData {
208 pub account: String,
210 pub currencies: Vec<String>,
212 pub booking: Option<String>,
214}
215
216#[derive(Debug, Clone, Serialize, Deserialize)]
218pub struct CloseData {
219 pub account: String,
221}
222
223#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct CommodityData {
226 pub currency: String,
228 #[serde(default)]
230 pub metadata: Vec<(String, MetaValueData)>,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
235pub struct PadData {
236 pub account: String,
238 pub source_account: String,
240}
241
242#[derive(Debug, Clone, Serialize, Deserialize)]
244pub struct EventData {
245 pub event_type: String,
247 pub value: String,
249}
250
251#[derive(Debug, Clone, Serialize, Deserialize)]
253pub struct NoteData {
254 pub account: String,
256 pub comment: String,
258}
259
260#[derive(Debug, Clone, Serialize, Deserialize)]
262pub struct DocumentData {
263 pub account: String,
265 pub path: String,
267}
268
269#[derive(Debug, Clone, Serialize, Deserialize)]
271pub struct PriceData {
272 pub currency: String,
274 pub amount: AmountData,
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize)]
280pub struct QueryData {
281 pub name: String,
283 pub query: String,
285}
286
287#[derive(Debug, Clone, Serialize, Deserialize)]
289pub struct CustomData {
290 pub custom_type: String,
292 pub values: Vec<String>,
294}
295
296#[derive(Debug, Clone, Default, Serialize, Deserialize)]
298pub struct PluginOptions {
299 pub operating_currencies: Vec<String>,
301 pub title: Option<String>,
303}
304
305#[derive(Debug, Clone, Serialize, Deserialize)]
307pub struct PluginError {
308 pub message: String,
310 pub source_file: Option<String>,
312 pub line_number: Option<u32>,
314 pub severity: PluginErrorSeverity,
316}
317
318#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
320pub enum PluginErrorSeverity {
321 #[serde(rename = "warning")]
323 Warning,
324 #[serde(rename = "error")]
326 Error,
327}
328
329impl PluginError {
330 pub fn error(message: impl Into<String>) -> Self {
332 Self {
333 message: message.into(),
334 source_file: None,
335 line_number: None,
336 severity: PluginErrorSeverity::Error,
337 }
338 }
339
340 pub fn warning(message: impl Into<String>) -> Self {
342 Self {
343 message: message.into(),
344 source_file: None,
345 line_number: None,
346 severity: PluginErrorSeverity::Warning,
347 }
348 }
349
350 pub fn at(mut self, file: impl Into<String>, line: u32) -> Self {
352 self.source_file = Some(file.into());
353 self.line_number = Some(line);
354 self
355 }
356}
357
358impl PluginOutput {
359 pub const fn passthrough(directives: Vec<DirectiveWrapper>) -> Self {
361 Self {
362 directives,
363 errors: Vec::new(),
364 }
365 }
366}