1use super::{Output, SequenceAccept, Writable, WritableSeq};
27
28pub struct NoOp;
30
31impl<O> Writable<O> for NoOp
32where
33    O: Output,
34{
35    async fn write_to(&self, _: &mut O) -> Result<(), O::Error> {
36        Ok(())
37    }
38}
39
40pub struct NoOpSeq;
42
43impl<O> WritableSeq<O> for NoOpSeq
44where
45    O: Output,
46{
47    async fn for_each<S: SequenceAccept<O>>(&self, _: &mut S) -> Result<(), O::Error> {
48        Ok(())
49    }
50}
51
52pub struct Combined<W1, W2>(pub W1, pub W2);
54
55impl<O, W1, W2> Writable<O> for Combined<W1, W2>
56where
57    O: Output,
58    W1: Writable<O>,
59    W2: Writable<O>,
60{
61    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
62        self.0.write_to(output).await?;
63        self.1.write_to(output).await
64    }
65}
66
67pub struct CombinedSeq<S1, S2>(pub S1, pub S2);
69
70impl<O, S1, S2> WritableSeq<O> for CombinedSeq<S1, S2>
71where
72    O: Output,
73    S1: WritableSeq<O>,
74    S2: WritableSeq<O>,
75{
76    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
77    where
78        S: SequenceAccept<O>,
79    {
80        self.0.for_each(sink).await?;
81        self.1.for_each(sink).await
82    }
83}
84
85pub struct SingularSeq<W>(pub W);
88
89impl<O, W> WritableSeq<O> for SingularSeq<W>
90where
91    O: Output,
92    W: Writable<O>,
93{
94    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
95    where
96        S: SequenceAccept<O>,
97    {
98        sink.accept(&self.0).await
99    }
100}
101
102pub struct RepeatSeq<W> {
105    pub count: usize,
107    pub writable: W,
109}
110
111impl<O, W> WritableSeq<O> for RepeatSeq<W>
112where
113    O: Output,
114    W: Writable<O>,
115{
116    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
117    where
118        S: SequenceAccept<O>,
119    {
120        for _ in 0..self.count {
121            sink.accept(&self.writable).await?;
122        }
123        Ok(())
124    }
125}
126
127pub struct ArrSeq<'a, W>(pub &'a [W]);
129
130impl<O, W> WritableSeq<O> for ArrSeq<'_, W>
131where
132    O: Output,
133    W: Writable<O>,
134{
135    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
136    where
137        S: SequenceAccept<O>,
138    {
139        for elem in self.0 {
140            sink.accept(elem).await?;
141        }
142        Ok(())
143    }
144}
145
146pub struct Str<STR>(pub STR);
149
150impl<O, STR> Writable<O> for Str<STR>
151where
152    O: Output,
153    STR: AsRef<str>,
154{
155    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
156        output.write(self.0.as_ref()).await
157    }
158}
159
160pub struct StrArrSeq<'a>(pub &'a [&'a str]);
162
163impl<O> WritableSeq<O> for StrArrSeq<'_>
164where
165    O: Output,
166{
167    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
168    where
169        S: SequenceAccept<O>,
170    {
171        for elem in self.0 {
172            sink.accept(&Str(*elem)).await?;
173        }
174        Ok(())
175    }
176}
177
178pub struct SeparatedSeqAccept<'o, O, Intro, Sep> {
181    pub output: &'o mut O,
183    pub intro: Intro,
185    pub separator: Sep,
187    pub wrote_any: bool,
189}
190
191impl<'o, O, Intro, Sep> SeparatedSeqAccept<'o, O, Intro, Sep> {
192    pub fn new(output: &'o mut O, intro: Intro, separator: Sep) -> Self {
193        Self {
194            output,
195            intro,
196            separator,
197            wrote_any: false,
198        }
199    }
200}
201
202impl<'o, O, Sep> SeparatedSeqAccept<'o, O, NoOp, Sep> {
203    pub fn no_intro(output: &'o mut O, separator: Sep) -> Self {
204        Self::new(output, NoOp, separator)
205    }
206}
207
208impl<'o, O> SeparatedSeqAccept<'o, O, NoOp, Str<&'static str>> {
209    pub fn comma_separated(output: &'o mut O) -> Self {
211        Self::new(output, NoOp, Str(", "))
212    }
213}
214
215impl<'o, O, Intro, Sep> SequenceAccept<O> for SeparatedSeqAccept<'o, O, Intro, Sep>
216where
217    O: Output,
218    Intro: Writable<O>,
219    Sep: Writable<O>,
220{
221    async fn accept<W>(&mut self, writable: &W) -> Result<(), O::Error>
222    where
223        W: Writable<O>,
224    {
225        if self.wrote_any {
226            self.separator.write_to(self.output).await?;
227        } else {
228            self.intro.write_to(self.output).await?;
229            self.wrote_any = true;
230        }
231        writable.write_to(self.output).await
232    }
233}
234
235pub struct SeqArrViaConfig<'t, T, Config> {
238    pub data: &'t [T],
239    pub config: Config,
240}
241
242pub trait WritableDatumConfig<T, O>
244where
245    O: Output,
246{
247    async fn write_datum(&self, datum: &T, output: &mut O) -> Result<(), O::Error>;
249}
250
251impl<'t, T, Config, O> WritableSeq<O> for SeqArrViaConfig<'t, T, Config>
252where
253    O: Output,
254    Config: WritableDatumConfig<T, O>,
255{
256    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
257    where
258        S: SequenceAccept<O>,
259    {
260        struct WriteSingle<'t, T, Config> {
261            datum: &'t T,
262            config: &'t Config,
263        }
264        impl<'t, T, Config, O> Writable<O> for WriteSingle<'t, T, Config> where O: Output, Config: WritableDatumConfig<T, O> {
265            async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
266                self.config.write_datum(self.datum, output).await
267            }
268        }
269        for datum in self.data {
270            sink.accept(&WriteSingle { datum, config: &self.config }).await?;
271        }
272        Ok(())
273    }
274}