1use super::{Output, SequenceAccept, Writable, WritableSeq};
27
28#[derive(Copy, Clone, Debug)]
30pub struct NoOp;
31
32impl<O> Writable<O> for NoOp
33where
34    O: Output,
35{
36    async fn write_to(&self, _: &mut O) -> Result<(), O::Error> {
37        Ok(())
38    }
39}
40
41#[derive(Copy, Clone, Debug)]
43pub struct NoOpSeq;
44
45impl<O> WritableSeq<O> for NoOpSeq
46where
47    O: Output,
48{
49    async fn for_each<S: SequenceAccept<O>>(&self, _: &mut S) -> Result<(), O::Error> {
50        Ok(())
51    }
52}
53
54#[derive(Clone, Debug)]
56pub struct Combined<W1, W2>(pub W1, pub W2);
57
58impl<O, W1, W2> Writable<O> for Combined<W1, W2>
59where
60    O: Output,
61    W1: Writable<O>,
62    W2: Writable<O>,
63{
64    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
65        self.0.write_to(output).await?;
66        self.1.write_to(output).await
67    }
68}
69
70#[derive(Clone, Debug)]
72pub struct CombinedSeq<S1, S2>(pub S1, pub S2);
73
74impl<O, S1, S2> WritableSeq<O> for CombinedSeq<S1, S2>
75where
76    O: Output,
77    S1: WritableSeq<O>,
78    S2: WritableSeq<O>,
79{
80    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
81    where
82        S: SequenceAccept<O>,
83    {
84        self.0.for_each(sink).await?;
85        self.1.for_each(sink).await
86    }
87}
88
89#[derive(Clone, Debug)]
92pub struct SingularSeq<W>(pub W);
93
94impl<O, W> WritableSeq<O> for SingularSeq<W>
95where
96    O: Output,
97    W: Writable<O>,
98{
99    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
100    where
101        S: SequenceAccept<O>,
102    {
103        sink.accept(&self.0).await
104    }
105}
106
107#[derive(Clone, Debug)]
110pub struct RepeatSeq<W> {
111    pub count: usize,
113    pub writable: W,
115}
116
117impl<O, W> WritableSeq<O> for RepeatSeq<W>
118where
119    O: Output,
120    W: Writable<O>,
121{
122    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
123    where
124        S: SequenceAccept<O>,
125    {
126        for _ in 0..self.count {
127            sink.accept(&self.writable).await?;
128        }
129        Ok(())
130    }
131}
132
133#[derive(Debug)]
135pub struct ArrSeq<'a, W>(pub &'a [W]);
136
137impl<'a, W> Clone for ArrSeq<'a, W> {
138    fn clone(&self) -> Self {
139        Self(self.0)
140    }
141}
142
143impl<O, W> WritableSeq<O> for ArrSeq<'_, W>
144where
145    O: Output,
146    W: Writable<O>,
147{
148    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
149    where
150        S: SequenceAccept<O>,
151    {
152        for elem in self.0 {
153            sink.accept(elem).await?;
154        }
155        Ok(())
156    }
157}
158
159#[derive(Copy, Clone, Debug)]
162pub struct Str<STR>(pub STR);
163
164impl<O, STR> Writable<O> for Str<STR>
165where
166    O: Output,
167    STR: AsRef<str>,
168{
169    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
170        output.write(self.0.as_ref()).await
171    }
172}
173
174#[derive(Clone, Debug)]
176pub struct StrArrSeq<'a>(pub &'a [&'a str]);
177
178impl<O> WritableSeq<O> for StrArrSeq<'_>
179where
180    O: Output,
181{
182    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
183    where
184        S: SequenceAccept<O>,
185    {
186        for elem in self.0 {
187            sink.accept(&Str(*elem)).await?;
188        }
189        Ok(())
190    }
191}
192
193#[derive(Debug)]
196pub struct SeparatedSeqAccept<'o, O, Intro, Sep> {
197    pub output: &'o mut O,
199    pub intro: Intro,
201    pub separator: Sep,
203    pub wrote_any: bool,
205}
206
207impl<'o, O, Intro, Sep> SeparatedSeqAccept<'o, O, Intro, Sep> {
208    pub fn new(output: &'o mut O, intro: Intro, separator: Sep) -> Self {
209        Self {
210            output,
211            intro,
212            separator,
213            wrote_any: false,
214        }
215    }
216}
217
218impl<'o, O, Sep> SeparatedSeqAccept<'o, O, NoOp, Sep> {
219    pub fn no_intro(output: &'o mut O, separator: Sep) -> Self {
220        Self::new(output, NoOp, separator)
221    }
222}
223
224impl<'o, O> SeparatedSeqAccept<'o, O, NoOp, Str<&'static str>> {
225    pub fn comma_separated(output: &'o mut O) -> Self {
227        Self::new(output, NoOp, Str(", "))
228    }
229}
230
231impl<'o, O, Intro, Sep> SequenceAccept<O> for SeparatedSeqAccept<'o, O, Intro, Sep>
232where
233    O: Output,
234    Intro: Writable<O>,
235    Sep: Writable<O>,
236{
237    async fn accept<W>(&mut self, writable: &W) -> Result<(), O::Error>
238    where
239        W: Writable<O>,
240    {
241        if self.wrote_any {
242            self.separator.write_to(self.output).await?;
243        } else {
244            self.intro.write_to(self.output).await?;
245            self.wrote_any = true;
246        }
247        writable.write_to(self.output).await
248    }
249}
250
251#[derive(Debug)]
254pub struct SurroundingSeqAccept<'o, O, Before, After> {
255    pub output: &'o mut O,
256    pub before: Before,
257    pub after: After,
258}
259
260impl<'o, O, Before, After> SurroundingSeqAccept<'o, O, Before, After> {
261    pub fn new(output: &'o mut O, before: Before, after: After) -> Self {
262        Self {
263            output,
264            before,
265            after,
266        }
267    }
268}
269
270impl<'o, O, Before, After> SequenceAccept<O> for SurroundingSeqAccept<'o, O, Before, After>
271where
272    O: Output,
273    Before: Writable<O>,
274    After: Writable<O>,
275{
276    async fn accept<W>(&mut self, writable: &W) -> Result<(), O::Error>
277    where
278        W: Writable<O>,
279    {
280        self.before.write_to(self.output).await?;
281        writable.write_to(self.output).await?;
282        self.after.write_to(self.output).await
283    }
284}
285
286#[derive(Debug)]
289pub struct SequenceViaConfig<'t, T, Config> {
290    pub data: &'t [T],
291    pub config: Config,
292}
293
294impl<'t, T, Config> Clone for SequenceViaConfig<'t, T, Config>
295where
296    Config: Clone,
297{
298    fn clone(&self) -> Self {
299        Self {
300            data: self.data,
301            config: self.config.clone(),
302        }
303    }
304}
305
306pub trait SequenceConfig<T, O>
308where
309    O: Output,
310{
311    async fn write_datum(&self, datum: &T, output: &mut O) -> Result<(), O::Error>;
313}
314
315impl<'t, T, Config, O> WritableSeq<O> for SequenceViaConfig<'t, T, Config>
316where
317    O: Output,
318    Config: SequenceConfig<T, O>,
319{
320    async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
321    where
322        S: SequenceAccept<O>,
323    {
324        struct WriteSingle<'t, T, Config> {
325            datum: &'t T,
326            config: &'t Config,
327        }
328        impl<'t, T, Config, O> Writable<O> for WriteSingle<'t, T, Config>
329        where
330            O: Output,
331            Config: SequenceConfig<T, O>,
332        {
333            async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
334                self.config.write_datum(self.datum, output).await
335            }
336        }
337        for datum in self.data {
338            sink.accept(&WriteSingle {
339                datum,
340                config: &self.config,
341            })
342            .await?;
343        }
344        Ok(())
345    }
346}