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