rsip_dns/resolvables/
resolvable.rs1use crate::resolvables::{ResolvableExt, ResolvableItem, ResolvableState};
2use async_trait::async_trait;
3use std::collections::VecDeque;
4
5#[derive(Debug, Clone)]
6pub struct Resolvable<T>(ResolvableInner<T>)
7where
8 T: ResolvableItem;
9
10#[async_trait]
11impl<T> ResolvableExt<T> for Resolvable<T>
12where
13 T: ResolvableItem,
14{
15 fn state(&self) -> ResolvableState {
16 self.0.state()
17 }
18
19 async fn resolve_next(&mut self) -> Option<T> {
20 self.0.resolve_next().await
21 }
22}
23
24impl<T> Resolvable<T>
25where
26 T: ResolvableItem,
27{
28 pub fn unset() -> Self {
29 Self(ResolvableInner::Unset)
30 }
31
32 pub fn empty() -> Self {
33 Self(ResolvableInner::Empty)
34 }
35
36 pub fn non_empty(stuff: impl Into<VecDeque<T>>) -> Self {
37 Self(ResolvableInner::NonEmpty(stuff.into()))
38 }
39}
40
41impl<T> Default for Resolvable<T>
42where
43 T: ResolvableItem,
44{
45 fn default() -> Self {
46 Self(Default::default())
47 }
48}
49
50impl<T> From<Vec<T>> for Resolvable<T>
51where
52 T: ResolvableItem,
53{
54 fn from(from: Vec<T>) -> Self {
55 Self(from.into())
56 }
57}
58
59#[derive(Debug, Clone)]
60enum ResolvableInner<T>
61where
62 T: ResolvableItem,
63{
64 Unset,
65 Empty,
66 NonEmpty(VecDeque<T>),
67}
68
69#[async_trait]
70impl<T> ResolvableExt<T> for ResolvableInner<T>
71where
72 T: ResolvableItem,
73{
74 fn state(&self) -> ResolvableState {
75 use ResolvableState::*;
76
77 match self {
78 Self::Unset => Unset,
79 Self::Empty => Empty,
80 Self::NonEmpty(_) => NonEmpty,
81 }
82 }
83
84 async fn resolve_next(&mut self) -> Option<T> {
85 match self {
86 Self::Unset => None,
87 Self::Empty => None,
88 Self::NonEmpty(data) => {
89 let element = data.pop_front();
90 if data.is_empty() {
91 *self = Self::Empty
92 }
93 element
94 }
95 }
96 }
97}
98
99impl<T> Default for ResolvableInner<T>
100where
101 T: ResolvableItem,
102{
103 fn default() -> Self {
104 Self::Unset
105 }
106}
107
108impl<T> From<Vec<T>> for ResolvableInner<T>
109where
110 T: ResolvableItem,
111{
112 fn from(from: Vec<T>) -> Self {
113 if from.is_empty() {
114 Self::Empty
115 } else {
116 Self::NonEmpty(from.into())
117 }
118 }
119}