parent
56bdb3bac7
commit
348bf4a90a
28 changed files with 311 additions and 105 deletions
@ -0,0 +1,28 @@ |
|||||||
|
use crate::UErrorBt; |
||||||
|
use crossbeam::channel::{self, Receiver, Sender}; |
||||||
|
use once_cell::sync::OnceCell; |
||||||
|
|
||||||
|
type ChanError = UErrorBt; |
||||||
|
static ERR_CHAN: OnceCell<ErrChan> = OnceCell::new(); |
||||||
|
|
||||||
|
pub struct ErrChan { |
||||||
|
tx: Sender<ChanError>, |
||||||
|
rx: Receiver<ChanError>, |
||||||
|
} |
||||||
|
|
||||||
|
impl ErrChan { |
||||||
|
fn get() -> &'static Self { |
||||||
|
ERR_CHAN.get_or_init(|| { |
||||||
|
let (tx, rx) = channel::bounded(20); |
||||||
|
Self { tx, rx } |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn send(msg: impl Into<UErrorBt>) { |
||||||
|
Self::get().tx.send(msg.into()).unwrap() |
||||||
|
} |
||||||
|
|
||||||
|
pub fn recv() -> ChanError { |
||||||
|
Self::get().rx.recv().unwrap() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
mod chan; |
||||||
|
mod variants; |
||||||
|
|
||||||
|
pub use chan::*; |
||||||
|
pub use variants::*; |
@ -1,6 +1,6 @@ |
|||||||
mod agent; |
mod agent; |
||||||
mod errors; |
mod error; |
||||||
mod jobs; |
mod jobs; |
||||||
pub mod schema; |
pub mod schema; |
||||||
|
|
||||||
pub use crate::models::{agent::*, errors::*, jobs::*}; |
pub use crate::models::{agent::*, error::*, jobs::*}; |
||||||
|
@ -0,0 +1,5 @@ |
|||||||
|
mod hexlify; |
||||||
|
mod stripped; |
||||||
|
|
||||||
|
pub use hexlify::*; |
||||||
|
pub use stripped::*; |
@ -0,0 +1,80 @@ |
|||||||
|
use std::fmt; |
||||||
|
use std::iter::Iterator; |
||||||
|
use std::slice::Iter as SliceIter; |
||||||
|
use std::str::Chars; |
||||||
|
|
||||||
|
const MAX_DATA_LEN: usize = 200; |
||||||
|
|
||||||
|
pub trait Strippable { |
||||||
|
//TODO: waiting for stabilizing GATs
|
||||||
|
type Item: fmt::Display; |
||||||
|
type TypeIter: Iterator<Item = Self::Item>; |
||||||
|
|
||||||
|
fn length(&self) -> usize; |
||||||
|
fn iterator(&self) -> Self::TypeIter; |
||||||
|
} |
||||||
|
|
||||||
|
impl<'a> Strippable for &'a str { |
||||||
|
type Item = char; |
||||||
|
type TypeIter = Chars<'a>; |
||||||
|
|
||||||
|
fn length(&self) -> usize { |
||||||
|
self.len() |
||||||
|
} |
||||||
|
|
||||||
|
fn iterator(&self) -> Self::TypeIter { |
||||||
|
self.chars() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl<'a> Strippable for &'a Vec<u8> { |
||||||
|
type Item = &'a u8; |
||||||
|
type TypeIter = SliceIter<'a, u8>; |
||||||
|
|
||||||
|
fn length(&self) -> usize { |
||||||
|
self.len() |
||||||
|
} |
||||||
|
|
||||||
|
fn iterator(&self) -> Self::TypeIter { |
||||||
|
self.iter() |
||||||
|
} |
||||||
|
} |
||||||
|
pub struct Stripped<'inner, Inner: Strippable + 'inner>(pub &'inner Inner); |
||||||
|
|
||||||
|
impl<'inner, Inner: Strippable + 'inner> Stripped<'inner, Inner> { |
||||||
|
fn iter(&self) -> Inner::TypeIter { |
||||||
|
self.0.iterator() |
||||||
|
} |
||||||
|
|
||||||
|
fn placeholder(&self) -> &'static str { |
||||||
|
if self.0.length() >= MAX_DATA_LEN { |
||||||
|
" <...>" |
||||||
|
} else { |
||||||
|
"" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl<'inner, Inner: Strippable + 'inner> fmt::Display for Stripped<'inner, Inner> { |
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
||||||
|
let placeholder = self.placeholder(); |
||||||
|
for c in self.iter().take(MAX_DATA_LEN - placeholder.len()) { |
||||||
|
write!(f, "{}", c)?; |
||||||
|
} |
||||||
|
write!(f, "{}", placeholder) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[cfg(test)] |
||||||
|
mod tests { |
||||||
|
use super::*; |
||||||
|
use rstest::*; |
||||||
|
|
||||||
|
#[rstest] |
||||||
|
#[case("abc", 3)] |
||||||
|
#[case("abcde".repeat(50), MAX_DATA_LEN)] |
||||||
|
fn test_strip(#[case] input: impl Into<String>, #[case] result_len: usize) { |
||||||
|
let s = input.into(); |
||||||
|
assert_eq!(Stripped(&s.as_str()).to_string().len(), result_len); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue