use std::fmt;
use std::collections::VecDeque;
use std::convert::TryInto;
use pancurses::{chtype, A_BOLD, COLOR_PAIR};
pub struct MessageQueue {
data: VecDeque<Message>,
pub closed: bool, }
impl MessageQueue {
pub fn new(capacity: usize, closed: bool) -> Self {
Self{data: VecDeque::with_capacity(capacity), closed}
}
pub fn pop(&mut self) -> Option<Message> { let message_check = self.data.front(); if message_check.is_none() { return None;
}
if self.closed {
self.push(self.data.front().unwrap().clone());
}
self.data.pop_front()
}
pub fn push(&mut self, message: Message) {
self.data.push_back(message);
}
pub fn push_update(&mut self, message: Message) {
if let Some(compare_msg) = self.data.iter_mut().rev().find(|cmp| cmp.id == message.id) { compare_msg.contents = message.contents;
} else {
self.push(message);
}
}
pub fn append(&mut self, mut messages: VecDeque<Message>){
self.data.append(&mut messages);
}
pub fn append_update(&mut self, messages: VecDeque<Message>){
messages.into_iter().for_each(|message| self.push_update(message));
}
pub fn drain(&mut self) -> VecDeque<Message> {
self.data.drain(..).collect::<VecDeque<Message>>()
}
}
pub type ColorString = Vec<ColorChar>;
#[derive(Copy, Clone)]
pub struct ColorChar {
pub data: u32,
pub attr: chtype
}
impl ColorChar {
pub fn new(data: u32, attr: chtype) -> Self {
Self{data, attr}
}
}
impl fmt::Debug for ColorChar {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("")
.field(&(self.data as u8 as char))
.field(&self.attr)
.finish()
}
}
pub struct Message {
pub contents: ColorString,
pub id: String,
}
impl Message {
pub fn new(contents: ColorString, id: &str) -> Self {
Self{contents, id: id.to_string()}
}
pub fn new_simple(string: &str, pair: i16, id: &str) -> Self {
let mut contents = ColorString::with_capacity(string.len());
for i in 0..string.len() {
contents.push(ColorChar::new(string.as_bytes()[i] as u32, COLOR_PAIR(pair.try_into().unwrap())));
}
Self::new(contents, id)
}
pub fn new_with_title(title: &str, body: &str, pair: i16, id: &str) -> Self { let color = COLOR_PAIR(pair.try_into().unwrap());
let mut contents = ColorString::with_capacity(title.len()+body.len());
for i in 0..title.len() {
contents.push(ColorChar::new(title.as_bytes()[i] as u32, color | A_BOLD));
}
for i in 0..body.len() {
contents.push(ColorChar::new(body.as_bytes()[i] as u32, color));
}
Self::new(contents, id)
}
pub fn len(&self) -> usize {
self.contents.len()
}
}
impl Clone for Message {
fn clone(&self) -> Message {
Message::new(self.contents.clone(), &self.id.clone())
}
}