use crate::Frames;
pub fn from_iter<I, F>(iter: I) -> FromIter<I::IntoIter, F>
where
I: IntoIterator<Item = F>,
I::IntoIter: Clone,
F: core::fmt::Display,
{
FromIter::new(iter.into_iter())
}
#[must_use]
pub fn empty() -> Empty {
Empty
}
#[must_use]
pub const fn dots() -> FromArray<10, &'static str> {
FromArray::new(["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
}
pub const fn from_array<const N: usize, F>(array: [F; N]) -> FromArray<N, F>
where
F: core::fmt::Display,
{
FromArray::new(array)
}
#[derive(Debug, Clone, Copy)]
pub struct FromIter<I, F>
where
I: Iterator<Item = F> + Clone,
F: core::fmt::Display,
{
start: I,
current: I,
frame: Option<F>,
}
impl<I, F> FromIter<I, F>
where
I: Iterator<Item = F> + Clone,
F: core::fmt::Display,
{
pub fn new(iter: I) -> Self {
let frame = iter.clone().next();
Self {
start: iter.clone(),
current: iter,
frame,
}
}
}
impl<I, F> core::fmt::Display for FromIter<I, F>
where
I: Iterator<Item = F> + Clone,
F: core::fmt::Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(frame) = &self.frame {
frame.fmt(f)?;
}
Ok(())
}
}
impl<I, F> Frames for FromIter<I, F>
where
I: Iterator<Item = F> + Clone + Send + Sync + 'static,
F: core::fmt::Display + Send + Sync + 'static,
{
fn advance(&mut self) {
if let Some(f) = self.current.next() {
self.frame = Some(f);
} else {
self.current = self.start.clone();
self.frame = self.current.next();
}
}
fn reset(&mut self) {
self.frame = self.start.clone().next();
self.current = self.start.clone();
}
}
pub struct Empty;
impl core::fmt::Display for Empty {
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Ok(())
}
}
impl Frames for Empty {
fn advance(&mut self) {}
fn print_len(&self) -> Option<usize> {
Some(0)
}
}
#[derive(Clone, Copy)]
pub struct FromArray<const N: usize, F>
where
F: core::fmt::Display,
{
idx: usize,
array: [F; N],
}
impl<const N: usize, F> FromArray<N, F>
where
F: core::fmt::Display,
{
#[must_use]
pub const fn new(array: [F; N]) -> Self {
assert!(N != 0, "the array cannot be empty.");
Self { idx: 0, array }
}
}
impl<const N: usize, F> core::fmt::Display for FromArray<N, F>
where
F: core::fmt::Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.array[self.idx].fmt(f)
}
}
impl<const N: usize, F> Frames for FromArray<N, F>
where
F: core::fmt::Display + Send + Sync + 'static,
{
fn advance(&mut self) {
if self.idx == self.array.len() - 1 {
self.idx = 0;
} else {
self.idx += 1;
}
}
fn reset(&mut self) {
self.idx = 0;
}
}