use super::{Output, SequenceAccept, Writable, WritableSeq};
#[derive(Copy, Clone, Debug)]
pub struct NoOp;
impl<O> Writable<O> for NoOp
where
O: Output,
{
async fn write_to(&self, _: &mut O) -> Result<(), O::Error> {
Ok(())
}
}
#[derive(Copy, Clone, Debug)]
pub struct NoOpSeq;
impl<O> WritableSeq<O> for NoOpSeq
where
O: Output,
{
async fn for_each<S: SequenceAccept<O>>(&self, _: &mut S) -> Result<(), O::Error> {
Ok(())
}
}
#[derive(Clone, Debug)]
pub struct Combined<W1, W2>(pub W1, pub W2);
impl<O, W1, W2> Writable<O> for Combined<W1, W2>
where
O: Output,
W1: Writable<O>,
W2: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
self.0.write_to(output).await?;
self.1.write_to(output).await
}
}
#[derive(Clone, Debug)]
pub struct CombinedSeq<S1, S2>(pub S1, pub S2);
impl<O, S1, S2> WritableSeq<O> for CombinedSeq<S1, S2>
where
O: Output,
S1: WritableSeq<O>,
S2: WritableSeq<O>,
{
async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
where
S: SequenceAccept<O>,
{
self.0.for_each(sink).await?;
self.1.for_each(sink).await
}
}
#[derive(Clone, Debug)]
pub struct SingularSeq<W>(pub W);
impl<O, W> WritableSeq<O> for SingularSeq<W>
where
O: Output,
W: Writable<O>,
{
async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
where
S: SequenceAccept<O>,
{
sink.accept(&self.0).await
}
}
#[derive(Clone, Debug)]
pub struct RepeatSeq<W>(pub usize, pub W);
impl<O, W> WritableSeq<O> for RepeatSeq<W>
where
O: Output,
W: Writable<O>,
{
async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
where
S: SequenceAccept<O>,
{
for _ in 0..self.0 {
sink.accept(&self.1).await?;
}
Ok(())
}
}
#[derive(Debug)]
pub struct ArrSeq<'a, W>(pub &'a [W]);
impl<'a, W> Clone for ArrSeq<'a, W> {
fn clone(&self) -> Self {
Self(self.0)
}
}
impl<O, W> WritableSeq<O> for ArrSeq<'_, W>
where
O: Output,
W: Writable<O>,
{
async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
where
S: SequenceAccept<O>,
{
for elem in self.0 {
sink.accept(elem).await?;
}
Ok(())
}
}
#[derive(Copy, Clone, Debug)]
pub struct Str<STR>(pub STR);
impl<O, STR> Writable<O> for Str<STR>
where
O: Output,
STR: AsRef<str>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
output.write(self.0.as_ref()).await
}
}
#[derive(Clone, Debug)]
pub struct StrArrSeq<'a>(pub &'a [&'a str]);
impl<O> WritableSeq<O> for StrArrSeq<'_>
where
O: Output,
{
async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
where
S: SequenceAccept<O>,
{
for elem in self.0 {
sink.accept(&Str(*elem)).await?;
}
Ok(())
}
}
#[derive(Debug)]
pub struct SeparatedSeqAccept<'o, O, Intro, Sep> {
pub output: &'o mut O,
pub intro: Intro,
pub separator: Sep,
pub wrote_any: bool,
}
impl<'o, O, Intro, Sep> SeparatedSeqAccept<'o, O, Intro, Sep> {
pub fn new(output: &'o mut O, intro: Intro, separator: Sep) -> Self {
Self {
output,
intro,
separator,
wrote_any: false,
}
}
}
impl<'o, O, Sep> SeparatedSeqAccept<'o, O, NoOp, Sep> {
pub fn no_intro(output: &'o mut O, separator: Sep) -> Self {
Self::new(output, NoOp, separator)
}
}
impl<'o, O> SeparatedSeqAccept<'o, O, NoOp, Str<&'static str>> {
pub fn comma_separated(output: &'o mut O) -> Self {
Self::new(output, NoOp, Str(", "))
}
}
impl<'o, O, Intro, Sep> SequenceAccept<O> for SeparatedSeqAccept<'o, O, Intro, Sep>
where
O: Output,
Intro: Writable<O>,
Sep: Writable<O>,
{
async fn accept<W>(&mut self, writable: &W) -> Result<(), O::Error>
where
W: Writable<O>,
{
if self.wrote_any {
self.separator.write_to(self.output).await?;
} else {
self.intro.write_to(self.output).await?;
self.wrote_any = true;
}
writable.write_to(self.output).await
}
}
#[derive(Debug)]
pub struct SurroundingSeqAccept<'o, O, Before, After> {
pub output: &'o mut O,
pub before: Before,
pub after: After,
}
impl<'o, O, Before, After> SurroundingSeqAccept<'o, O, Before, After> {
pub fn new(output: &'o mut O, before: Before, after: After) -> Self {
Self {
output,
before,
after,
}
}
}
impl<'o, O, Before, After> SequenceAccept<O> for SurroundingSeqAccept<'o, O, Before, After>
where
O: Output,
Before: Writable<O>,
After: Writable<O>,
{
async fn accept<W>(&mut self, writable: &W) -> Result<(), O::Error>
where
W: Writable<O>,
{
self.before.write_to(self.output).await?;
writable.write_to(self.output).await?;
self.after.write_to(self.output).await
}
}
#[derive(Debug)]
pub struct SequenceViaConfig<'t, T, Config> {
pub data: &'t [T],
pub config: Config,
}
impl<'t, T, Config> Clone for SequenceViaConfig<'t, T, Config>
where
Config: Clone,
{
fn clone(&self) -> Self {
Self {
data: self.data,
config: self.config.clone(),
}
}
}
pub trait SequenceConfig<T, O>
where
O: Output,
{
async fn write_datum(&self, datum: &T, output: &mut O) -> Result<(), O::Error>;
}
impl<'t, T, Config, O> WritableSeq<O> for SequenceViaConfig<'t, T, Config>
where
O: Output,
Config: SequenceConfig<T, O>,
{
async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
where
S: SequenceAccept<O>,
{
struct WriteSingle<'t, T, Config> {
datum: &'t T,
config: &'t Config,
}
impl<'t, T, Config, O> Writable<O> for WriteSingle<'t, T, Config>
where
O: Output,
Config: SequenceConfig<T, O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
self.config.write_datum(self.datum, output).await
}
}
for datum in self.data {
sink.accept(&WriteSingle {
datum,
config: &self.config,
})
.await?;
}
Ok(())
}
}
pub struct BoxedIndirection<W>(pub W);
impl<O, W> Writable<O> for BoxedIndirection<W>
where
O: Output,
W: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
Box::pin(self.0.write_to(output)).await
}
}
impl<O, W> WritableSeq<O> for BoxedIndirection<W>
where
O: Output,
W: WritableSeq<O>,
{
async fn for_each<S>(&self, sink: &mut S) -> Result<(), O::Error>
where
S: SequenceAccept<O>,
{
Box::pin(self.0.for_each(sink)).await
}
}