/ bin / app / src / util / mod.rs
mod.rs
  1  /* This file is part of DarkFi (https://dark.fi)
  2   *
  3   * Copyright (C) 2020-2025 Dyne.org foundation
  4   *
  5   * This program is free software: you can redistribute it and/or modify
  6   * it under the terms of the GNU Affero General Public License as
  7   * published by the Free Software Foundation, either version 3 of the
  8   * License, or (at your option) any later version.
  9   *
 10   * This program is distributed in the hope that it will be useful,
 11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13   * GNU Affero General Public License for more details.
 14   *
 15   * You should have received a copy of the GNU Affero General Public License
 16   * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 17   */
 18  
 19  #[cfg(target_os = "linux")]
 20  use colored::Colorize;
 21  use std::time::{SystemTime, UNIX_EPOCH};
 22  
 23  pub mod i18n;
 24  mod rt;
 25  pub use rt::{AsyncRuntime, ExecutorPtr};
 26  
 27  /// Use src/util/time.rs Timestamp instead of this.
 28  pub fn unixtime() -> u64 {
 29      let timest = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
 30      assert!(timest < std::u64::MAX as u128);
 31      timest as u64
 32  }
 33  
 34  #[allow(dead_code)]
 35  pub fn ansi_texture(width: usize, height: usize, data: &Vec<u8>) -> String {
 36      let mut out = String::new();
 37  
 38      out.push('┌');
 39      for _ in 0..width {
 40          out.push('─');
 41      }
 42      out.push('┐');
 43      out.push('\n');
 44  
 45      for i in 0..height {
 46          out.push('│');
 47          for j in 0..width {
 48              let idx = 4 * (i * width + j);
 49  
 50              #[cfg(target_os = "android")]
 51              {
 52                  let a = data[idx + 3];
 53  
 54                  if a > 204 {
 55                      out.push('█');
 56                  } else if a > 153 {
 57                      out.push('▓');
 58                  } else if a > 102 {
 59                      out.push('▒');
 60                  } else if a > 51 {
 61                      out.push('░');
 62                  } else {
 63                      out.push(' ');
 64                  }
 65              }
 66  
 67              #[cfg(target_os = "linux")]
 68              {
 69                  let r = data[idx];
 70                  let g = data[idx + 1];
 71                  let b = data[idx + 2];
 72                  let a = data[idx + 3];
 73  
 74                  let r = ((a as f32 * r as f32) / 255.) as u8;
 75                  let g = ((a as f32 * g as f32) / 255.) as u8;
 76                  let b = ((a as f32 * b as f32) / 255.) as u8;
 77  
 78                  let val = "█".truecolor(r, g, b).to_string();
 79                  out.push_str(&val);
 80              }
 81          }
 82          out.push('│');
 83          out.push('\n');
 84      }
 85  
 86      out.push('└');
 87      for _ in 0..width {
 88          out.push('─');
 89      }
 90      out.push('┘');
 91      out.push('\n');
 92  
 93      out
 94  }
 95  
 96  pub struct TupleIterStruct3<I1, I2, I3> {
 97      idx: usize,
 98      i1: I1,
 99      i2: I2,
100      i3: I3,
101  }
102  
103  impl<I1, I2, I3> Iterator for TupleIterStruct3<I1, I2, I3>
104  where
105      I1: Iterator,
106      I2: Iterator,
107      I3: Iterator,
108  {
109      type Item = (usize, I1::Item, I2::Item, I3::Item);
110  
111      fn next(&mut self) -> Option<Self::Item> {
112          let Some(x1) = self.i1.next() else { return None };
113          let Some(x2) = self.i2.next() else { return None };
114          let Some(x3) = self.i3.next() else { return None };
115  
116          let res = (self.idx, x1, x2, x3);
117          self.idx += 1;
118  
119          Some(res)
120      }
121  }
122  
123  #[allow(dead_code)]
124  pub fn zip3<X1, X2, X3, I1, I2, I3>(i1: I1, i2: I2, i3: I3) -> TupleIterStruct3<I1, I2, I3>
125  where
126      I1: Iterator<Item = X1>,
127      I2: Iterator<Item = X2>,
128      I3: Iterator<Item = X3>,
129  {
130      TupleIterStruct3 { idx: 0, i1, i2, i3 }
131  }
132  
133  pub struct TupleIterStruct4<I1, I2, I3, I4> {
134      idx: usize,
135      i1: I1,
136      i2: I2,
137      i3: I3,
138      i4: I4,
139  }
140  
141  impl<I1, I2, I3, I4> Iterator for TupleIterStruct4<I1, I2, I3, I4>
142  where
143      I1: Iterator,
144      I2: Iterator,
145      I3: Iterator,
146      I4: Iterator,
147  {
148      type Item = (usize, I1::Item, I2::Item, I3::Item, I4::Item);
149  
150      fn next(&mut self) -> Option<Self::Item> {
151          let Some(x1) = self.i1.next() else { return None };
152          let Some(x2) = self.i2.next() else { return None };
153          let Some(x3) = self.i3.next() else { return None };
154          let Some(x4) = self.i4.next() else { return None };
155  
156          let res = (self.idx, x1, x2, x3, x4);
157          self.idx += 1;
158  
159          Some(res)
160      }
161  }
162  
163  #[allow(dead_code)]
164  pub fn zip4<X1, X2, X3, X4, I1, I2, I3, I4>(
165      i1: I1,
166      i2: I2,
167      i3: I3,
168      i4: I4,
169  ) -> TupleIterStruct4<I1, I2, I3, I4>
170  where
171      I1: Iterator<Item = X1>,
172      I2: Iterator<Item = X2>,
173      I3: Iterator<Item = X3>,
174      I4: Iterator<Item = X4>,
175  {
176      TupleIterStruct4 { idx: 0, i1, i2, i3, i4 }
177  }
178  
179  #[allow(dead_code)]
180  pub fn enumerate<X>(v: Vec<X>) -> impl Iterator<Item = (usize, X)> {
181      v.into_iter().enumerate()
182  }
183  #[allow(dead_code)]
184  pub fn enumerate_ref<X>(v: &Vec<X>) -> impl Iterator<Item = (usize, &X)> {
185      v.iter().enumerate()
186  }
187  pub fn enumerate_mut<X>(v: &mut Vec<X>) -> impl Iterator<Item = (usize, &mut X)> {
188      v.iter_mut().enumerate()
189  }