Lines
0 %
Functions
Branches
100 %
use crate::error::{Error, Result};
use scripting_format::{
ACCOUNT_DATA_SIZE, AccountData, COMMODITY_DATA_SIZE, CommodityData, EntityHeader, EntityType,
Operation, SPLIT_DATA_SIZE, SplitData, TAG_DATA_SIZE, TRANSACTION_DATA_SIZE, TagData,
TransactionData,
};
pub struct EntityRef<'a> {
pub header: EntityHeader,
pub data: &'a [u8],
pub strings_pool: &'a [u8],
}
impl<'a> EntityRef<'a> {
pub fn entity_type(&self) -> Result<EntityType> {
EntityType::try_from(self.header.entity_type).map_err(|()| Error::InvalidEntityType)
pub fn operation(&self) -> Result<Operation> {
Operation::try_from(self.header.operation).map_err(|()| Error::InvalidOperation)
#[must_use]
pub fn id(&self) -> [u8; 16] {
self.header.id
pub fn parent_idx(&self) -> i32 {
self.header.parent_idx
pub fn as_transaction(&self) -> Result<Transaction> {
if self.entity_type()? != EntityType::Transaction {
return Err(Error::InvalidEntityType);
if self.data.len() < TRANSACTION_DATA_SIZE {
return Err(Error::OutOfBounds);
let data = TransactionData::from_bytes(self.data).ok_or(Error::InvalidHeader)?;
Ok(Transaction {
header: self.header,
data,
})
pub fn as_split(&self) -> Result<Split> {
if self.entity_type()? != EntityType::Split {
if self.data.len() < SPLIT_DATA_SIZE {
let data = SplitData::from_bytes(self.data).ok_or(Error::InvalidHeader)?;
Ok(Split {
pub fn as_tag(&self) -> Result<Tag<'a>> {
if self.entity_type()? != EntityType::Tag {
if self.data.len() < TAG_DATA_SIZE {
let data = TagData::from_bytes(self.data).ok_or(Error::InvalidHeader)?;
Ok(Tag {
strings_pool: self.strings_pool,
pub fn as_account(&self) -> Result<Account<'a>> {
if self.entity_type()? != EntityType::Account {
if self.data.len() < ACCOUNT_DATA_SIZE {
let data = AccountData::from_bytes(self.data).ok_or(Error::InvalidHeader)?;
Ok(Account {
pub fn as_commodity(&self) -> Result<Commodity<'a>> {
if self.entity_type()? != EntityType::Commodity {
if self.data.len() < COMMODITY_DATA_SIZE {
let data = CommodityData::from_bytes(self.data).ok_or(Error::InvalidHeader)?;
Ok(Commodity {
pub struct Transaction {
pub data: TransactionData,
impl Transaction {
pub fn post_date(&self) -> i64 {
self.data.post_date
pub fn enter_date(&self) -> i64 {
self.data.enter_date
pub fn split_count(&self) -> u32 {
self.data.split_count
pub fn tag_count(&self) -> u32 {
self.data.tag_count
pub fn is_multi_currency(&self) -> bool {
self.data.is_multi_currency != 0
pub struct Split {
pub data: SplitData,
impl Split {
pub fn account_id(&self) -> [u8; 16] {
self.data.account_id
pub fn commodity_id(&self) -> [u8; 16] {
self.data.commodity_id
pub fn value_num(&self) -> i64 {
self.data.value_num
pub fn value_denom(&self) -> i64 {
self.data.value_denom
pub fn reconcile_state(&self) -> u8 {
self.data.reconcile_state
pub fn reconcile_date(&self) -> i64 {
self.data.reconcile_date
pub struct Tag<'a> {
pub data: TagData,
impl<'a> Tag<'a> {
pub fn name(&self) -> Result<&'a str> {
let start = self.data.name_offset as usize;
let end = start + self.data.name_len as usize;
if end > self.strings_pool.len() {
core::str::from_utf8(&self.strings_pool[start..end]).map_err(|_| Error::Utf8Error)
pub fn value(&self) -> Result<&'a str> {
let start = self.data.value_offset as usize;
let end = start + self.data.value_len as usize;
pub struct Account<'a> {
pub data: AccountData,
impl<'a> Account<'a> {
pub fn parent_account_id(&self) -> [u8; 16] {
self.data.parent_account_id
pub fn path(&self) -> Result<&'a str> {
let start = self.data.path_offset as usize;
let end = start + self.data.path_len as usize;
pub struct Commodity<'a> {
pub data: CommodityData,
impl<'a> Commodity<'a> {
pub fn symbol(&self) -> Result<&'a str> {
let start = self.data.symbol_offset as usize;
let end = start + self.data.symbol_len as usize;
pub fn fraction(&self) -> u32 {
self.data.fraction