async-codegen 0.12.1

Minimalist async-IO code generation framework.
Documentation
/*
 * Copyright © 2025 Anand Beh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use super::*;
use crate::common::{SeparatedSeqAccept, Str};
use crate::cstyle_common::{
    ModsAccept, TypeArgAccept, delegate_tuple_w, delegate_tuple_ws, delegate_tuple_ww,
};
use crate::{Output, Writable, WritableSeq};

impl<O, Type, Expr> Writable<O> for DeclareVarStmt<Type, Expr>
where
    O: Output,
    Type: Writable<O>,
    Expr: Writable<O>,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        Stmt(DeclareParam(&self.0, &self.1)).write_to(output).await
    }
}

impl<O, Assert> Writable<O> for AssertStmt<Assert>
where
    O: Output,
    Assert: Writable<O>,
{
    async fn write_to(&self, o: &mut O) -> Result<(), O::Error> {
        o.write("assert ").await?;
        self.0.write_to(o).await?;
        o.write(";\n").await
    }
}

delegate_tuple_w!(Stmt);

delegate_tuple_ww!(AssignStmt);

delegate_tuple_w!(ReturnStmt);

delegate_tuple_ww!(AssignExpr);

delegate_tuple_ww!(IfBlock);

delegate_tuple_ww!(Else);

delegate_tuple_w!(Block);

delegate_tuple_ww!(MemberAccess);

impl<O, Mods, Name, Body> Writable<O> for ClassDef<Mods, Name, Body>
where
    O: Output,
    Mods: WritableSeq<O>,
    Name: Writable<O>,
    Body: Writable<O>,
{
    async fn write_to(&self, o: &mut O) -> Result<(), O::Error> {
        self.mods.for_each(&mut ModsAccept(o)).await?;
        o.write("class ").await?;
        self.name.write_to(o).await?;
        o.write(" {\n").await?;
        self.body.write_to(o).await?;
        o.write("}\n").await
    }
}

impl<O, Mods, Name, Body> Writable<O> for InterfaceDef<Mods, Name, Body>
where
    O: Output,
    Mods: WritableSeq<O>,
    Name: Writable<O>,
    Body: Writable<O>,
{
    async fn write_to(&self, o: &mut O) -> Result<(), O::Error> {
        self.mods.for_each(&mut ModsAccept(o)).await?;
        o.write("interface ").await?;
        self.name.write_to(o).await?;
        o.write(" {\n").await?;
        self.body.write_to(o).await?;
        o.write("}\n").await
    }
}

impl<O, Expr, Super> Writable<O> for Extends<Expr, Super>
where
    O: Output,
    Expr: Writable<O>,
    Super: Writable<O>,
{
    async fn write_to(&self, o: &mut O) -> Result<(), O::Error> {
        self.0.write_to(o).await?;
        o.write(" extends ").await?;
        self.1.write_to(o).await
    }
}

impl<O, Expr, Ifaces> Writable<O> for Implements<Expr, Ifaces>
where
    O: Output,
    Expr: Writable<O>,
    Ifaces: WritableSeq<O>,
{
    async fn write_to(&self, o: &mut O) -> Result<(), O::Error> {
        self.0.write_to(o).await?;
        self.1
            .for_each(&mut SeparatedSeqAccept::new(
                o,
                Str(" implements "),
                Str(", "),
            ))
            .await
    }
}

impl<O> Writable<O> for Modifier
where
    O: Output,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        output
            .write(match self {
                Self::Abstract => "abstract",
                Self::Default => "default",
                Self::Final => "final",
                Self::Native => "native",
                Self::Private => "private",
                Self::Protected => "protected",
                Self::Public => "public",
                Self::Static => "static",
                Self::StrictFp => "strictfp",
                Self::Synchronized => "synchronized",
                Self::Transient => "transient",
                Self::Volatile => "volatile",
            })
            .await
    }
}

impl<O, Name, Args> Writable<O> for FunctionCall<Name, Args>
where
    O: Output,
    Name: Writable<O>,
    Args: WritableSeq<O>,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        self.name.write_to(output).await?;
        output.write("(").await?;
        self.args
            .for_each(&mut SeparatedSeqAccept::comma_separated(output))
            .await?;
        output.write(")").await
    }
}

impl<O, Name, Args> Writable<O> for ConstructorCall<Name, Args>
where
    O: Output,
    Name: Writable<O>,
    Args: WritableSeq<O>,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        output.write("new ").await?;
        FunctionCall {
            name: &self.name,
            args: &self.args,
        }
        .write_to(output)
        .await
    }
}

impl<O, Type, Name> Writable<O> for DeclareParam<Type, Name>
where
    O: Output,
    Type: Writable<O>,
    Name: 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
    }
}

delegate_tuple_ws!(Parameterized);

impl<O, Name> Writable<O> for WithInference<Name>
where
    O: Output,
    Name: Writable<O>,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        self.0.write_to(output).await?;
        output.write("<>").await
    }
}

impl<O, Component> Writable<O> for Array<Component>
where
    O: Output,
    Component: Writable<O>,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        self.0.write_to(output).await?;
        output.write("[]").await
    }
}

impl<O, VarName, Iter, Body> Writable<O> for EnhancedFor<VarName, Iter, Body>
where
    O: Output,
    VarName: Writable<O>,
    Iter: Writable<O>,
    Body: Writable<O>,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        output.write("for (").await?;
        self.var_name.write_to(output).await?;
        output.write(" : ").await?;
        self.iter.write_to(output).await?;
        output.write(") {\n").await?;
        self.body.write_to(output).await?;
        output.write("}\n").await
    }
}

impl<O, Init, Predicate, Update, Body> Writable<O> for TraditionalFor<Init, Predicate, Update, Body>
where
    O: Output,
    Init: Writable<O>,
    Predicate: Writable<O>,
    Update: Writable<O>,
    Body: Writable<O>,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        output.write("for (").await?;
        self.init.write_to(output).await?;
        output.write("; ").await?;
        self.predicate.write_to(output).await?;
        output.write("; ").await?;
        self.update.write_to(output).await?;
        output.write(") {\n").await?;
        self.body.write_to(output).await?;
        output.write("}\n").await
    }
}

impl<O, Mods, TypeArgs, Name, Args, Throws, Body> Writable<O>
    for ConstructorDef<Mods, TypeArgs, Name, Args, Throws, Body>
where
    O: Output,
    Mods: WritableSeq<O>,
    TypeArgs: WritableSeq<O>,
    Name: Writable<O>,
    Args: WritableSeq<O>,
    Throws: WritableSeq<O>,
    Body: Writable<O>,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        self.mods.for_each(&mut ModsAccept(output)).await?;
        TypeArgAccept::new(output)
            .write_in_diamond_with_space_after(&self.type_args)
            .await?;
        FunctionCall {
            name: &self.name,
            args: &self.args,
        }
        .write_to(output)
        .await?;
        self.throws.for_each(&mut throws_decl(output)).await?;
        output.write(" {\n").await?;
        self.body.write_to(output).await?;
        output.write("}\n\n").await
    }
}

impl<O, Mods, TypeArgs, Return, Name, Args, Throws, Body> Writable<O>
    for FunctionDef<Mods, TypeArgs, Return, Name, Args, Throws, Body>
where
    O: Output,
    Mods: WritableSeq<O>,
    TypeArgs: WritableSeq<O>,
    Return: Writable<O>,
    Name: Writable<O>,
    Args: WritableSeq<O>,
    Throws: WritableSeq<O>,
    Body: Writable<O>,
{
    async fn write_to(&self, output: &mut O) -> Result<(), O::Error> {
        self.mods.for_each(&mut ModsAccept(output)).await?;
        TypeArgAccept::new(output)
            .write_in_diamond_with_space_after(&self.type_args)
            .await?;
        self.return_type.write_to(output).await?;
        output.write(" ").await?;
        FunctionCall {
            name: &self.name,
            args: &self.args,
        }
        .write_to(output)
        .await?;
        self.throws.for_each(&mut throws_decl(output)).await?;
        output.write(" {\n").await?;
        self.body.write_to(output).await?;
        output.write("}\n\n").await
    }
}

fn throws_decl<'o, O>(
    output: &'o mut O,
) -> SeparatedSeqAccept<'o, O, Str<&'static str>, Str<&'static str>> {
    SeparatedSeqAccept::new(output, Str(" throws "), Str(", "))
}