use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ParseResult {
pub ledger: Option<Ledger>,
pub errors: Vec<Error>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Ledger {
pub directives: Vec<DirectiveJson>,
pub options: LedgerOptions,
}
#[derive(
Debug, Clone, Default, Serialize, Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize,
)]
pub struct LedgerOptions {
pub operating_currencies: Vec<String>,
pub title: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
#[allow(missing_docs)]
pub enum DirectiveJson {
#[serde(rename = "transaction")]
Transaction {
date: String,
flag: String,
payee: Option<String>,
narration: Option<String>,
tags: Vec<String>,
links: Vec<String>,
postings: Vec<PostingJson>,
},
#[serde(rename = "balance")]
Balance {
date: String,
account: String,
amount: AmountValue,
},
#[serde(rename = "open")]
Open {
date: String,
account: String,
currencies: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
booking: Option<String>,
},
#[serde(rename = "close")]
Close { date: String, account: String },
#[serde(rename = "commodity")]
Commodity { date: String, currency: String },
#[serde(rename = "pad")]
Pad {
date: String,
account: String,
source_account: String,
},
#[serde(rename = "event")]
Event {
date: String,
event_type: String,
value: String,
},
#[serde(rename = "note")]
Note {
date: String,
account: String,
comment: String,
},
#[serde(rename = "document")]
Document {
date: String,
account: String,
path: String,
},
#[serde(rename = "price")]
Price {
date: String,
currency: String,
amount: AmountValue,
},
#[serde(rename = "query")]
Query {
date: String,
name: String,
query_string: String,
},
#[serde(rename = "custom")]
Custom { date: String, custom_type: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PostingJson {
pub account: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub units: Option<AmountValue>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cost: Option<PostingCostJson>,
#[serde(skip_serializing_if = "Option::is_none")]
pub price: Option<AmountValue>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PostingCostJson {
#[serde(skip_serializing_if = "Option::is_none")]
pub number_per: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub currency: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Serialize,
Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(rename_all = "lowercase")]
pub enum Severity {
Error,
Warning,
}
#[derive(
Debug, Clone, Serialize, Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize,
)]
pub struct Error {
pub message: String,
pub line: Option<u32>,
pub column: Option<u32>,
pub severity: Severity,
}
impl Error {
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
line: None,
column: None,
severity: Severity::Error,
}
}
pub fn with_line(message: impl Into<String>, line: u32) -> Self {
Self {
message: message.into(),
line: Some(line),
column: None,
severity: Severity::Error,
}
}
pub fn warning(message: impl Into<String>) -> Self {
Self {
message: message.into(),
line: None,
column: None,
severity: Severity::Warning,
}
}
}
impl From<rustledger_loader::LedgerError> for Error {
fn from(e: rustledger_loader::LedgerError) -> Self {
Self {
message: e.message,
line: e.location.as_ref().map(|loc| loc.line as u32),
column: e.location.as_ref().map(|loc| loc.column as u32),
severity: match e.severity {
rustledger_loader::ErrorSeverity::Error => Severity::Error,
rustledger_loader::ErrorSeverity::Warning => Severity::Warning,
},
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationResult {
pub valid: bool,
pub errors: Vec<Error>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QueryResult {
pub columns: Vec<String>,
pub rows: Vec<Vec<CellValue>>,
pub errors: Vec<Error>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
#[allow(missing_docs)]
pub enum CellValue {
Null,
String(String),
Integer(i64),
Boolean(bool),
Amount { number: String, currency: String },
Position {
units: AmountValue,
#[serde(skip_serializing_if = "Option::is_none")]
cost: Option<CostValue>,
},
Inventory { positions: Vec<PositionValue> },
StringSet(Vec<String>),
Set(Vec<Box<Self>>),
Object(std::collections::HashMap<String, Box<Self>>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AmountValue {
pub number: String,
pub currency: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PositionValue {
pub units: AmountValue,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CostValue {
pub number: String,
pub currency: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FormatResult {
pub formatted: Option<String>,
pub errors: Vec<Error>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PadResult {
pub directives: Vec<DirectiveJson>,
pub padding_transactions: Vec<DirectiveJson>,
pub errors: Vec<Error>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginResult {
pub directives: Vec<DirectiveJson>,
pub errors: Vec<Error>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginInfo {
pub name: String,
pub description: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionJson {
pub text: String,
pub category: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionResultJson {
pub completions: Vec<CompletionJson>,
pub context: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorCompletion {
pub label: String,
pub kind: CompletionKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub insert_text: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum CompletionKind {
Keyword,
Account,
AccountSegment,
Currency,
Payee,
Date,
Text,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorCompletionResult {
pub completions: Vec<EditorCompletion>,
pub context: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorHoverInfo {
pub contents: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub range: Option<EditorRange>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorRange {
pub start_line: u32,
pub start_character: u32,
pub end_line: u32,
pub end_character: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorLocation {
pub line: u32,
pub character: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorDocumentSymbol {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<String>,
pub kind: SymbolKind,
pub range: EditorRange,
#[serde(skip_serializing_if = "Option::is_none")]
pub children: Option<Vec<Self>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deprecated: Option<bool>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum SymbolKind {
Transaction,
Account,
Balance,
Commodity,
Posting,
Pad,
Event,
Note,
Document,
Price,
Query,
Custom,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ReferenceKind {
Account,
Currency,
Payee,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorReference {
pub range: EditorRange,
pub kind: ReferenceKind,
pub is_definition: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorReferencesResult {
pub symbol: String,
pub kind: ReferenceKind,
pub references: Vec<EditorReference>,
}