1use std::collections::{HashSet, HashMap};
2
3use bc_components::{ARID, PublicKeys, PrivateKeyBase};
4use bc_envelope::prelude::*;
5
6use crate::Receipt;
7
8
9pub fn prefix(s: &str, len: usize) -> String {
10 s.chars().take(len).collect()
11}
12
13pub trait Prefix {
14 fn prefix(&self, len: usize) -> String;
15}
16
17impl<T> Prefix for T
18where
19 T: AsRef<str>,
20{
21 fn prefix(&self, len: usize) -> String {
22 prefix(self.as_ref(), len)
23 }
24}
25
26
27pub fn suffix(s: &str, len: usize) -> String {
28 s.chars().rev().take(len).collect::<String>().chars().rev().collect()
29}
30
31pub trait Suffix {
32 fn suffix(&self, len: usize) -> String;
33}
34
35impl<T> Suffix for T
36where
37 T: AsRef<str>,
38{
39 fn suffix(&self, len: usize) -> String {
40 suffix(self.as_ref(), len)
41 }
42}
43
44
45pub fn flanked_by(s: &str, left: &str, right: &str) -> String {
46 left.to_owned() + s + right
47}
48
49pub trait FlankedBy {
50 fn flanked_by(&self, left: &str, right: &str) -> String;
51}
52
53impl<T> FlankedBy for T
54where
55 T: AsRef<str>,
56{
57 fn flanked_by(&self, left: &str, right: &str) -> String {
58 flanked_by(self.as_ref(), left, right)
59 }
60}
61
62pub fn flanked_abbrev(s: &str) -> String {
63 s.flanked_by("<", ">")
64}
65
66pub trait FlankedAbbrev {
67 fn flanked_abbrev(&self) -> String;
68}
69
70impl<T> FlankedAbbrev for T
71where
72 T: AsRef<str>,
73{
74 fn flanked_abbrev(&self) -> String {
75 flanked_abbrev(self.as_ref())
76 }
77}
78
79pub fn flanked_function(s: &str) -> String {
80 s.flanked_by("«", "»")
81}
82
83pub trait FlankedFunction {
84 fn flanked_function(&self) -> String;
85}
86
87impl<T> FlankedFunction for T
88where
89 T: AsRef<str>,
90{
91 fn flanked_function(&self) -> String {
92 flanked_function(self.as_ref())
93 }
94}
95
96pub trait Abbrev {
97 fn abbrev(&self) -> String;
98}
99
100fn abbreviate_string(s: impl AsRef<str>) -> String {
101 s.as_ref().prefix(8).flanked_abbrev()
102}
103
104fn abbreviate_opt_string(s: Option<impl AsRef<str>>) -> String {
105 if let Some(s) = s {
106 abbreviate_string(s)
107 } else {
108 "<None>".to_string()
109 }
110}
111
112impl Abbrev for str {
113 fn abbrev(&self) -> String {
114 abbreviate_string(self)
115 }
116}
117
118impl Abbrev for String {
119 fn abbrev(&self) -> String {
120 abbreviate_string(self)
121 }
122}
123
124impl Abbrev for Option<String> {
125 fn abbrev(&self) -> String {
126 abbreviate_opt_string(self.as_deref())
127 }
128}
129
130impl Abbrev for Option<&String> {
131 fn abbrev(&self) -> String {
132 abbreviate_opt_string(self.as_deref())
133 }
134}
135
136impl Abbrev for Option<&str> {
137 fn abbrev(&self) -> String {
138 abbreviate_opt_string(self.as_deref())
139 }
140}
141
142impl Abbrev for ARID {
143 fn abbrev(&self) -> String {
144 self.ur_string().suffix(8).flanked_abbrev()
145 }
146}
147
148impl Abbrev for PublicKeys {
149 fn abbrev(&self) -> String {
150 self.ur_string().suffix(8).flanked_abbrev()
151 }
152}
153
154impl Abbrev for PrivateKeyBase {
155 fn abbrev(&self) -> String {
156 self.ur_string().suffix(8).flanked_abbrev()
157 }
158}
159
160impl Abbrev for Envelope {
161 fn abbrev(&self) -> String {
162 self.ur_string().suffix(8).flanked_abbrev()
163 }
164}
165
166impl Abbrev for Receipt {
167 fn abbrev(&self) -> String {
168 let envelope: Envelope = self.clone().into();
169 envelope.ur_string().suffix(8).flanked_abbrev()
170 }
171}
172
173impl Abbrev for ByteString {
174 fn abbrev(&self) -> String {
175 format!("{} bytes", self.len()).flanked_abbrev()
176 }
177}
178
179impl<T> Abbrev for Vec<T>
180where
181 T: Abbrev,
182{
183 fn abbrev(&self) -> String {
184 let mut items = self.iter().map(|i| i.abbrev()).collect::<Vec<_>>();
185 items.sort();
186 items.join(", ").flanked_by("[", "]")
187 }
188}
189
190impl<T> Abbrev for HashSet<T>
191where
192 T: Abbrev,
193{
194 fn abbrev(&self) -> String {
195 let mut items = self.iter().map(|i| i.abbrev()).collect::<Vec<_>>();
196 items.sort();
197 items.join(", ").flanked_by("[", "]")
198 }
199}
200
201impl<K, V> Abbrev for HashMap<K, V>
202where
203 K: Abbrev,
204 V: Abbrev,
205{
206 fn abbrev(&self) -> String {
207 let mut items = self
208 .iter()
209 .map(|(k, v)| format!("{}: {}", k.abbrev(), v.abbrev()))
210 .collect::<Vec<_>>();
211 items.sort();
212 items.join(", ").flanked_by("{", "}")
213 }
214}