rsip-dns 0.1.4

SIP Rust library implementing RFC 3263, implemented on top of rsip
Documentation
use crate::resolvables::{ResolvableExt, ResolvableItem, ResolvableState};
use async_trait::async_trait;
use std::collections::VecDeque;

#[derive(Debug, Clone)]
pub struct Resolvable<T>(ResolvableInner<T>)
where
    T: ResolvableItem;

#[async_trait]
impl<T> ResolvableExt<T> for Resolvable<T>
where
    T: ResolvableItem,
{
    fn state(&self) -> ResolvableState {
        self.0.state()
    }

    async fn resolve_next(&mut self) -> Option<T> {
        self.0.resolve_next().await
    }
}

impl<T> Resolvable<T>
where
    T: ResolvableItem,
{
    pub fn unset() -> Self {
        Self(ResolvableInner::Unset)
    }

    pub fn empty() -> Self {
        Self(ResolvableInner::Empty)
    }

    pub fn non_empty(stuff: impl Into<VecDeque<T>>) -> Self {
        Self(ResolvableInner::NonEmpty(stuff.into()))
    }
}

impl<T> Default for Resolvable<T>
where
    T: ResolvableItem,
{
    fn default() -> Self {
        Self(Default::default())
    }
}

impl<T> From<Vec<T>> for Resolvable<T>
where
    T: ResolvableItem,
{
    fn from(from: Vec<T>) -> Self {
        Self(from.into())
    }
}

#[derive(Debug, Clone)]
enum ResolvableInner<T>
where
    T: ResolvableItem,
{
    Unset,
    Empty,
    NonEmpty(VecDeque<T>),
}

#[async_trait]
impl<T> ResolvableExt<T> for ResolvableInner<T>
where
    T: ResolvableItem,
{
    fn state(&self) -> ResolvableState {
        use ResolvableState::*;

        match self {
            Self::Unset => Unset,
            Self::Empty => Empty,
            Self::NonEmpty(_) => NonEmpty,
        }
    }

    async fn resolve_next(&mut self) -> Option<T> {
        match self {
            Self::Unset => None,
            Self::Empty => None,
            Self::NonEmpty(data) => {
                let element = data.pop_front();
                if data.is_empty() {
                    *self = Self::Empty
                }
                element
            }
        }
    }
}

impl<T> Default for ResolvableInner<T>
where
    T: ResolvableItem,
{
    fn default() -> Self {
        Self::Unset
    }
}

impl<T> From<Vec<T>> for ResolvableInner<T>
where
    T: ResolvableItem,
{
    fn from(from: Vec<T>) -> Self {
        if from.is_empty() {
            Self::Empty
        } else {
            Self::NonEmpty(from.into())
        }
    }
}