1#![doc = include_str!("../README.md")]
2
3use std::collections::BTreeMap;
4
5use brk_computer::Computer;
6use brk_error::Result;
7use brk_indexer::Indexer;
8use brk_structs::Height;
9use tabled::settings::Style;
10use vecdb::{AnyCollectableVec, AnyStoredVec};
11
12mod deser;
13mod format;
14mod index;
15mod maybe_ids;
16mod output;
17mod pagination;
18mod params;
19mod table;
20mod vecs;
21
22pub use format::Format;
23pub use index::Index;
24pub use output::{Output, Value};
25pub use pagination::{PaginatedIndexParam, PaginationParam};
26pub use params::{IdParam, Params, ParamsOpt};
27pub use table::Tabled;
28use vecs::Vecs;
29
30use crate::vecs::{IdToVec, IndexToVec};
31
32#[allow(dead_code)]
33pub struct Interface<'a> {
34 vecs: Vecs<'a>,
35 indexer: &'a Indexer,
36 computer: &'a Computer,
37}
38
39impl<'a> Interface<'a> {
40 pub fn build(indexer: &Indexer, computer: &Computer) -> Self {
41 let indexer = indexer.static_clone();
42 let computer = computer.static_clone();
43 let vecs = Vecs::build(indexer, computer);
44
45 Self {
46 vecs,
47 indexer,
48 computer,
49 }
50 }
51
52 pub fn get_height(&self) -> Height {
53 Height::from(self.indexer.vecs.height_to_blockhash.stamp())
54 }
55
56 pub fn search(&self, params: &Params) -> Vec<(String, &&dyn AnyCollectableVec)> {
57 let tuples = params
58 .ids
59 .iter()
60 .flat_map(|s| {
61 s.to_lowercase()
62 .replace("-", "_")
63 .split_whitespace()
64 .flat_map(|s| {
65 s.split(',')
66 .flat_map(|s| s.split('+').map(|s| s.to_string()))
67 })
68 .collect::<Vec<_>>()
69 })
70 .map(|mut id| {
71 let mut res = self.vecs.id_to_index_to_vec.get(id.as_str());
72 if res.is_none()
73 && let Ok(index) = Index::try_from(id.as_str())
74 {
75 id = index.possible_values().last().unwrap().to_string();
76 res = self.vecs.id_to_index_to_vec.get(id.as_str())
77 }
78 (id, res)
79 })
80 .filter(|(_, opt)| opt.is_some())
81 .map(|(id, vec)| (id, vec.unwrap()))
82 .collect::<Vec<_>>();
83
84 tuples
85 .iter()
86 .flat_map(|(str, i_to_v)| i_to_v.get(¶ms.index).map(|vec| (str.to_owned(), vec)))
87 .collect::<Vec<_>>()
88 }
89
90 pub fn format(
91 &self,
92 vecs: Vec<(String, &&dyn AnyCollectableVec)>,
93 params: &ParamsOpt,
94 ) -> Result<Output> {
95 let from = params.from().map(|from| {
96 vecs.iter()
97 .map(|(_, v)| v.i64_to_usize(from))
98 .min()
99 .unwrap_or_default()
100 });
101
102 let to = params.to().map(|to| {
103 vecs.iter()
104 .map(|(_, v)| v.i64_to_usize(to))
105 .min()
106 .unwrap_or_default()
107 });
108
109 let mut values = vecs
110 .iter()
111 .map(|(_, vec)| -> Result<Vec<serde_json::Value>> {
112 Ok(vec.collect_range_serde_json(from, to)?)
113 })
114 .collect::<Result<Vec<_>>>()?;
115
116 let format = params.format();
117
118 if values.is_empty() {
119 return Ok(Output::default(format));
120 }
121
122 let ids_last_i = vecs.len() - 1;
123
124 Ok(match format {
125 Some(Format::CSV) | Some(Format::TSV) => {
126 let delimiter = if format == Some(Format::CSV) {
127 ','
128 } else {
129 '\t'
130 };
131
132 let mut text = vecs
133 .iter()
134 .map(|(id, _)| id.to_owned())
135 .collect::<Vec<_>>()
136 .join(&delimiter.to_string());
137
138 text.push('\n');
139
140 let values_len = values.first().unwrap().len();
141
142 (0..values_len).for_each(|i| {
143 let mut line = "".to_string();
144 values.iter().enumerate().for_each(|(id_i, v)| {
145 line += &v.get(i).unwrap().to_string();
146 if id_i == ids_last_i {
147 line.push('\n');
148 } else {
149 line.push(delimiter);
150 }
151 });
152 text += &line;
153 });
154
155 if format == Some(Format::CSV) {
156 Output::CSV(text)
157 } else {
158 Output::TSV(text)
159 }
160 }
161 Some(Format::MD) => {
162 let mut table =
163 values.to_table(vecs.iter().map(|(s, _)| s.to_owned()).collect::<Vec<_>>());
164
165 table.with(Style::markdown());
166
167 Output::MD(table.to_string())
168 }
169 Some(Format::JSON) | None => {
170 if values.len() == 1 {
171 let mut values = values.pop().unwrap();
172 if values.len() == 1 {
173 let value = values.pop().unwrap();
174 Output::Json(Value::Single(value))
175 } else {
176 Output::Json(Value::List(values))
177 }
178 } else {
179 Output::Json(Value::Matrix(values))
180 }
181 }
182 })
183 }
184
185 pub fn search_and_format(&self, params: Params) -> Result<Output> {
186 self.format(self.search(¶ms), ¶ms.rest)
187 }
188
189 pub fn id_to_index_to_vec(&self) -> &BTreeMap<&str, IndexToVec<'_>> {
190 &self.vecs.id_to_index_to_vec
191 }
192
193 pub fn index_to_id_to_vec(&self) -> &BTreeMap<Index, IdToVec<'_>> {
194 &self.vecs.index_to_id_to_vec
195 }
196
197 pub fn get_vecid_count(&self) -> usize {
198 self.vecs.id_count
199 }
200
201 pub fn get_index_count(&self) -> usize {
202 self.vecs.index_count
203 }
204
205 pub fn get_vec_count(&self) -> usize {
206 self.vecs.vec_count
207 }
208
209 pub fn get_indexes(&self) -> &[&'static str] {
210 &self.vecs.indexes
211 }
212
213 pub fn get_accepted_indexes(&self) -> &BTreeMap<&'static str, &'static [&'static str]> {
214 &self.vecs.accepted_indexes
215 }
216
217 pub fn get_vecids(&self, pagination: PaginationParam) -> &[&str] {
218 self.vecs.ids(pagination)
219 }
220
221 pub fn get_index_to_vecids(&self, paginated_index: PaginatedIndexParam) -> Vec<&str> {
222 self.vecs.index_to_ids(paginated_index)
223 }
224
225 pub fn get_vecid_to_indexes(&self, id: String) -> Option<&Vec<&'static str>> {
226 self.vecs.id_to_indexes(id)
227 }
228}