okane_core/report/
commodity.rs1use std::{collections::HashMap, fmt::Display};
4
5use bumpalo::Bump;
6
7use crate::syntax::pretty_decimal::PrettyDecimal;
8
9use super::intern::{FromInterned, InternError, InternStore, InternedStr};
10
11#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
13pub struct Commodity<'arena>(InternedStr<'arena>);
14
15impl<'arena> FromInterned<'arena> for Commodity<'arena> {
16 fn from_interned(v: InternedStr<'arena>) -> Self {
17 Self(v)
18 }
19
20 fn as_interned(&self) -> InternedStr<'arena> {
21 self.0
22 }
23}
24
25impl Display for Commodity<'_> {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 self.as_str().fmt(f)
28 }
29}
30
31impl<'arena> Commodity<'arena> {
32 pub fn as_str(&self) -> &'arena str {
34 self.0.as_str()
35 }
36}
37
38#[derive(Debug, PartialEq, Eq, Hash, Clone)]
41pub struct OwnedCommodity(String);
42
43impl OwnedCommodity {
44 pub fn from_string(v: String) -> Self {
46 Self(v)
47 }
48
49 pub fn as_str(&self) -> &str {
51 self.0.as_str()
52 }
53
54 pub fn into_string(self) -> String {
56 self.0
57 }
58}
59
60impl From<Commodity<'_>> for OwnedCommodity {
61 fn from(value: Commodity<'_>) -> Self {
62 Self(value.as_str().to_string())
63 }
64}
65
66impl Display for OwnedCommodity {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 self.0.fmt(f)
69 }
70}
71
72pub(super) struct CommodityStore<'arena> {
74 intern: InternStore<'arena, Commodity<'arena>>,
75 formatting: HashMap<Commodity<'arena>, PrettyDecimal>,
76}
77
78impl<'arena> CommodityStore<'arena> {
79 pub fn new(arena: &'arena Bump) -> Self {
81 Self {
82 intern: InternStore::new(arena),
83 formatting: HashMap::new(),
84 }
85 }
86
87 pub fn ensure(&mut self, value: &str) -> Commodity<'arena> {
91 self.intern.ensure(value)
92 }
93
94 pub fn resolve(&self, value: &str) -> Option<Commodity<'arena>> {
96 self.intern.resolve(value)
97 }
98
99 pub(super) fn insert_canonical(
103 &mut self,
104 value: &str,
105 ) -> Result<Commodity<'arena>, InternError> {
106 self.intern.insert_canonical(value)
107 }
108
109 pub(super) fn insert_alias(
113 &mut self,
114 value: &str,
115 canonical: Commodity<'arena>,
116 ) -> Result<(), InternError> {
117 self.intern.insert_alias(value, canonical)
118 }
119
120 #[inline]
121 pub(super) fn get_decimal_point(&self, commodity: Commodity<'arena>) -> Option<u32> {
122 self.formatting.get(&commodity).map(|x| x.value.scale())
123 }
124
125 #[inline]
126 pub(super) fn set_format(&mut self, commodity: Commodity<'arena>, format: PrettyDecimal) {
127 self.formatting.insert(commodity, format);
128 }
129}