use crate::{Output, SequenceAccept, Writable, WritableSeq};
pub struct Stmt<Expr>(pub Expr);
pub struct AssignStmt<Variable, Expr>(pub Variable, pub Expr);
pub struct ReturnStmt<Expr>(pub Expr);
pub struct AssignExpr<Variable, Expr>(pub Variable, pub Expr);
pub struct IfBlock<Cond, Body>(pub Cond, pub Body);
pub struct Else<Before, After>(pub Before, pub After);
pub struct Block<Body>(pub Body);
pub struct MemberAccess<Owner, Member>(pub Owner, pub Member);
pub struct Quoted<A>(pub A);
pub struct Parameterized<Name, TypeArgs>(pub Name, pub TypeArgs);
macro_rules! delegate_tuple_w {
($element:ident) => {
impl<O, Part> Writable<O> for $element<Part>
where
O: Output,
Part: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
$crate::cstyle_common::$element(&self.0)
.write_to(output)
.await
}
}
};
}
pub(crate) use delegate_tuple_w;
macro_rules! delegate_tuple_ww {
($element:ident) => {
impl<O, Part1, Part2> Writable<O> for $element<Part1, Part2>
where
O: Output,
Part1: Writable<O>,
Part2: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
$crate::cstyle_common::$element(&self.0, &self.1)
.write_to(output)
.await
}
}
};
}
pub(crate) use delegate_tuple_ww;
macro_rules! delegate_tuple_ws {
($element:ident) => {
impl<O, Part1, Part2> Writable<O> for $element<Part1, Part2>
where
O: Output,
Part1: Writable<O>,
Part2: WritableSeq<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
$crate::cstyle_common::$element(&self.0, &self.1)
.write_to(output)
.await
}
}
};
}
pub(crate) use delegate_tuple_ws;
use crate::common::{SeparatedSeqAccept, Str};
impl<O, Expr> Writable<O> for Stmt<Expr>
where
O: Output,
Expr: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
self.0.write_to(output).await?;
output.write(";\n").await
}
}
impl<O: Output, Variable, Expr> Writable<O> for AssignStmt<Variable, Expr>
where
Variable: Writable<O>,
Expr: Writable<O>,
{
async fn write_to(&self, o: &mut O) -> Result<(), O::Error> {
Stmt(AssignExpr(&self.0, &self.1)).write_to(o).await
}
}
impl<O, Expr> Writable<O> for ReturnStmt<Expr>
where
O: Output,
Expr: Writable<O>,
{
async fn write_to(&self, o: &mut O) -> Result<(), O::Error> {
o.write("return ").await?;
self.0.write_to(o).await?;
o.write(";\n").await
}
}
impl<O, Variable, Expr> Writable<O> for AssignExpr<Variable, Expr>
where
O: Output,
Variable: Writable<O>,
Expr: Writable<O>,
{
async fn write_to(&self, o: &mut O) -> Result<(), O::Error> {
self.0.write_to(o).await?;
o.write(" = ").await?;
self.1.write_to(o).await
}
}
impl<O, Cond, Body> Writable<O> for IfBlock<Cond, Body>
where
O: Output,
Cond: Writable<O>,
Body: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
output.write("if ").await?;
self.0.write_to(output).await?;
output.write(" {\n").await?;
self.1.write_to(output).await?;
output.write("\n}").await
}
}
impl<O, Before, After> Writable<O> for Else<Before, After>
where
O: Output,
Before: Writable<O>,
After: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
self.0.write_to(output).await?;
output.write(" else ").await?;
self.1.write_to(output).await
}
}
impl<O, Body> Writable<O> for Block<Body>
where
O: Output,
Body: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
output.write("{\n").await?;
self.0.write_to(output).await?;
output.write("\n}").await
}
}
impl<O, Owner, Member> Writable<O> for MemberAccess<Owner, Member>
where
O: Output,
Owner: Writable<O>,
Member: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
self.0.write_to(output).await?;
output.write(".").await?;
self.1.write_to(output).await
}
}
impl<O, A> Writable<O> for Quoted<A>
where
O: Output,
A: Writable<O>,
{
async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
output.write("\"").await?;
self.0.write_to(output).await?;
output.write("\"").await
}
}
impl<O, Name, TypeArgs> Writable<O> for Parameterized<Name, TypeArgs>
where
O: Output,
Name: Writable<O>,
TypeArgs: WritableSeq<O>,
{
async fn write_to(&self, o: &mut O) -> Result<(), O::Error> {
self.0.write_to(o).await?;
TypeArgAccept::new(o).write_in_diamond(&self.1).await
}
}
pub struct TypeArgAccept<'o, O> {
inner: SeparatedSeqAccept<'o, O, Str<&'static str>, Str<&'static str>>,
}
impl<'o, O> TypeArgAccept<'o, O> {
pub fn new(output: &'o mut O) -> Self {
Self {
inner: SeparatedSeqAccept::new(output, Str("<"), Str(", ")),
}
}
}
impl<'o, O> TypeArgAccept<'o, O>
where
O: Output,
{
pub async fn write_in_diamond<TypeArgs>(&mut self, type_args: &TypeArgs) -> Result<(), O::Error>
where
TypeArgs: WritableSeq<O>,
{
self.write_with_suffix(type_args, ">").await
}
pub async fn write_in_diamond_with_space_after<TypeArgs>(
&mut self,
type_args: &TypeArgs,
) -> Result<(), O::Error>
where
TypeArgs: WritableSeq<O>,
{
self.write_with_suffix(type_args, "> ").await
}
async fn write_with_suffix<TypeArgs>(
&mut self,
type_args: &TypeArgs,
suffix: &str,
) -> Result<(), O::Error>
where
TypeArgs: WritableSeq<O>,
{
type_args.for_each(&mut self.inner).await?;
if self.inner.wrote_any {
self.inner.output.write(suffix).await?;
}
Ok(())
}
}
pub struct ModsAccept<'o, O>(pub &'o mut O);
impl<'o, O: Output> SequenceAccept<O> for ModsAccept<'o, O> {
async fn accept<W>(&mut self, writable: &W) -> Result<(), O::Error>
where
W: Writable<O>,
{
writable.write_to(&mut self.0).await?;
self.0.write(" ").await
}
}