async_codegen/rust/
mod.rs

1/*
2 * Copyright © 2025 Anand Beh
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16use crate::common::NoOp;
17
18mod syntax;
19
20/// All possible Rust editions.
21/// This is the only type in this module meant to be used as context, and not as a writable itself.
22#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
23#[non_exhaustive]
24pub enum Edition {
25    /// This Rust edition is declared for usability purposes. However, not all [crate::Writable]
26    /// implementations are guaranteed to work with it.
27    Rust2015,
28    Rust2018,
29    Rust2021,
30    Rust2024,
31}
32
33#[cfg(test)]
34mod test_edition {
35    use crate::rust::Edition;
36
37    #[test]
38    fn edition_order() {
39        assert!(Edition::Rust2018 < Edition::Rust2021);
40        assert!(Edition::Rust2018 < Edition::Rust2024);
41    }
42}
43
44/// An attribute enabled conditionally, i.e. `#[cfg_attr(Cond, Attr)]`
45pub struct CfgAttr<Cond, Attr>(pub Cond, pub Attr);
46
47/// The no mangle attribute.
48///
49/// Requires that the context satisfies [ContextProvides] for [Edition], because in Rust 2024 and
50/// beyond, the no-mangle attribute is an "unsafe attribute.
51pub struct NoMangle;
52
53/// The attribute content for `allow(...)`. The tuple value must be a sequence.
54pub struct AllowLints<Lints>(pub Lints);
55
56/// The deprecated attribute. The three variants of this enum correspond to the deprecated
57/// attribute's multiple ways of being specified. See:
58/// https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute
59pub enum Deprecated<Msg, Since = NoOp> {
60    Basic,
61    Message(Msg),
62    Full { since: Since, note: Msg },
63}
64
65impl Default for Deprecated<NoOp, NoOp> {
66    fn default() -> Self {
67        Self::Basic
68    }
69}
70
71impl Deprecated<NoOp, NoOp> {
72    pub fn basic() -> Self {
73        Self::Basic
74    }
75}
76
77impl<Msg> Deprecated<Msg> {
78    pub fn with_message(msg: Msg) -> Self {
79        Self::Message(msg)
80    }
81}
82
83/// The must_use attribute
84pub struct MustUse;
85
86/// The public modifier
87pub struct ModPub;
88
89/// The extern modifier, with the ABI selected as the tuple value
90pub struct ModExtern<Abi>(pub Abi);
91
92/// A let statement. This statement includes the semicolon and a new line.
93pub struct LetStmt<Variable, Expr>(pub Variable, pub Expr);
94
95/// An item attached to an associated container, via "::".
96/// The output will look like `Cont::Item`.
97pub struct AssociatedItem<Cont, Item>(pub Cont, pub Item);
98
99/// A question mark following another expression.
100pub struct QuestionMarkAfter<Expr>(pub Expr);
101
102/// Wraps an expression in `Ok(EXPR)`.
103pub struct OkResultOf<Expr>(pub Expr);
104
105/// Uses the `as` expression to perform a qualified trait cast (ready for a method call).
106/// I.e., this will render as `<Type as Trait>`.
107pub struct TypeAsTrait<Type, Trait>(pub Type, pub Trait);
108
109/// Declaration of an extern block, i.e. for FFI.
110pub struct ExternBlock<Attr, Abi, Body> {
111    /// The attributes. Must be a sequence, and each value will be placed inside `#[]`.
112    pub attr: Attr,
113    /// The ABI chosen. Must be writable
114    pub abi: Abi,
115    /// The body of the extern block. Must be writable
116    pub body: Body,
117}
118
119/// Places the expression inside an unsafe block.
120/// Adds new lines inside the brackets, wrapping the inner expression.
121pub struct UnsafeBlock<Expr>(pub Expr);
122
123/// Writes a closure.
124/// Adds new lines inside the brackets, wrapping the inner expression.
125pub struct Closure<InputVars, Expr> {
126    /// The input variables.
127    /// Should be a sequence. They will be comma separated and placed within the pipes.
128    /// To use no input variables, use [crate::common::NoOpSeq].
129    pub input_vars: InputVars,
130    /// The expression inside the closure block.
131    pub inside_block: Expr,
132}
133
134/// Performs a call to a function inside code.
135pub struct FunctionCall<Recv, FuncName, Args> {
136    /// The function receiver
137    pub receiver: Recv,
138    /// Whether the function is associated, false if it's a method
139    pub is_assoc: bool,
140    /// The function being called
141    pub function: Function<FuncName, Args>,
142}
143
144/// The base struct for a function. Includes name and arguments.
145/// This function is re-used in other places and is likely not helpful by itself.
146pub struct Function<Name, Args> {
147    /// The function name. Must be writable.
148    pub name: Name,
149    /// The function arguments. Must be a sequence.
150    pub args: Args,
151}
152
153/// A function declaration
154pub struct FunctionDef<Attr, Mods, Name, Args, Return, Body> {
155    /// The attributes. Must be a sequence, and each value will be placed inside `#[]`.
156    pub attr: Attr,
157    /// The modifiers. Must be a sequence.
158    pub mods: Mods,
159    /// The function itself
160    pub decl: Function<Name, Args>,
161    /// The return type, i.e. after the `->` arrow
162    pub return_type: Return,
163    /// The function body. At the minimum, this must be `;` (see [`FunctionBodyDeclare`])
164    pub body: Body,
165}
166
167/// Declares a function body. This is equivalent to just a semicolon.
168pub struct FunctionBodyDeclare;
169
170/// Renders as `Type=Value`. Intended to be used as a type argument, to specify associated types.
171pub struct AssociatedTypeEquals<Type, Value>(pub Type, pub Value);
172
173/// Adds a "dyn " before a type expression.
174pub struct DynOf<Type>(pub Type);
175
176/// Adds a "&" before a type expression
177pub struct RefOf<Type>(pub Type);
178
179/// Adds a "impl " before a type expression
180pub struct ImplOf<Type>(pub Type);
181
182/// Adds a reference with a lifetime before a type expression, i.e. `&'<lifetime> <type>`
183pub struct LifetimedRefOf<'l, Type>(pub &'l str, pub Type);
184
185/// Declares an associated type, rendering as `type VarName = Value;`.
186/// Adds new lines before and after.
187pub struct AssociatedTypeDef<VarName, Value>(pub VarName, pub Value);
188
189/// The declaration of a trait
190pub struct TraitDef<Attr, Mods, Name, TypeVars, SuperTraits, Body> {
191    /// The trait attributes. Must be a sequence, and each value will be placed inside `#[]`.
192    pub attr: Attr,
193    /// The trait modifiers, e.g. visibility. Must be a sequence.
194    pub mods: Mods,
195    /// The name of the trait
196    pub name: Name,
197    /// The type variables. Must be a sequence
198    pub type_variables: TypeVars,
199    /// The super traits. Must be a sequence
200    pub super_traits: SuperTraits,
201    /// The trait definition's body. Use [crate::common::NoOp] if none exists.
202    pub body: Body,
203}
204
205/// The implementation declaration for a trait, applying to a certain receiver.
206pub struct TraitImpl<TypeVars, Trait, Recv, Body> {
207    /// The type variables to use for the impl block itself. All type variables that appear later
208    /// on the trait or the receiver must be declared here, per Rust language rules.
209    ///
210    /// This field must be a sequence.
211    pub type_variables: TypeVars,
212    /// The trait being implemented
213    pub the_trait: Trait,
214    /// The receiver for which it is implemented
215    pub receiver: Recv,
216    /// The body. Use [crate::common::NoOp] if none exists.
217    pub body: Body,
218}
219
220/// A type argument-parameterized expression. Used in relation to parameterized names and their
221/// arguments. Examples: `function_name<args>`, `TypeName<'lifetime, args>`, `MyType<Assoc=Value>`.
222///
223/// If no type args exist, [`crate::common::NoOpSeq`] should be used.
224pub struct Parameterized<Name, TypeArgs> {
225    name: Name,
226    type_args: TypeArgs,
227}
228
229impl<Name, TypeArgs> Parameterized<Name, TypeArgs> {
230    /// Initializes an instance
231    pub fn new(name: Name, type_args: TypeArgs) -> Self {
232        Self { name, type_args }
233    }
234}
235
236/// A type variable with a sequence of bounds.
237/// Will render as `TypeVar: B1 + B2 + ...`
238pub struct BoundedTypeVar<TypeVar, Bounds>(pub TypeVar, pub Bounds);
239
240/// A standalone lifetime, intended to be used as a type argument or variable
241pub struct Lifetime<'l>(pub &'l str);
242
243/// Renders an individual function parameter, `Name: Type`
244pub struct FunctionParam<Name, Type>(pub Name, pub Type);
245
246/// A sequence acceptor that writes attributes
247pub struct AttributesAccept<'o, O>(pub &'o mut O);