Skip to main content

macroonz_compiler/token/generation/
traits.rs

1//! Conventional Rust trait and implementation shells assembled from exact generated-token runs.
2//!
3//! These operations own fixed trait, associated-item and implementation punctuation only.
4//! The caller owns every qualifier, name, generic, bound, predicate, path, item, body, safety contract and semantic meaning.
5
6use super::behavior::function_item;
7use super::compose::group;
8use super::items::{generic_parameters, where_clause};
9use super::{GeneratedDelimiter, GeneratedToken};
10use crate::bounded::Overflow;
11
12/// One trait declaration with exact qualifiers, parameters, supertraits, predicates and associated items.
13///
14/// Qualifiers are emitted exactly before `trait`, so an unsafe trait remains explicit caller authority.
15///
16/// # Errors
17///
18/// Returns [`Overflow`] where the associated-item body outgrows the declared generated-token magnitude.
19pub fn trait_declaration(
20    qualifiers: Vec<GeneratedToken>,
21    name: GeneratedToken,
22    parameters: Vec<Vec<GeneratedToken>>,
23    supertraits: Vec<Vec<GeneratedToken>>,
24    predicates: Vec<Vec<GeneratedToken>>,
25    items: Vec<GeneratedToken>,
26) -> Result<Vec<GeneratedToken>, Overflow> {
27    let mut tokens = qualifiers;
28    tokens.extend([GeneratedToken::word("trait"), name]);
29    tokens.extend(generic_parameters(parameters));
30    if !supertraits.is_empty() {
31        tokens.push(GeneratedToken::alone(':'));
32        tokens.extend(plus_many(supertraits));
33    }
34    tokens.extend(where_clause(predicates));
35    tokens.push(group(GeneratedDelimiter::Brace, items)?);
36    Ok(tokens)
37}
38
39/// One associated type declaration or definition.
40///
41/// An absent value emits a declaration, while a present value emits the exact definition.
42#[must_use]
43pub fn associated_type(
44    name: GeneratedToken,
45    parameters: Vec<Vec<GeneratedToken>>,
46    bounds: Vec<Vec<GeneratedToken>>,
47    value: Option<Vec<GeneratedToken>>,
48    predicates: Vec<Vec<GeneratedToken>>,
49) -> Vec<GeneratedToken> {
50    let mut tokens = vec![GeneratedToken::word("type"), name];
51    tokens.extend(generic_parameters(parameters));
52    if !bounds.is_empty() {
53        tokens.push(GeneratedToken::alone(':'));
54        tokens.extend(plus_many(bounds));
55    }
56    if let Some(value) = value {
57        tokens.push(GeneratedToken::alone('='));
58        tokens.extend(value);
59    }
60    tokens.extend(where_clause(predicates));
61    tokens.push(GeneratedToken::alone(';'));
62    tokens
63}
64
65/// One associated constant declaration or definition.
66///
67/// An absent value emits a declaration, while a present value emits the exact definition.
68#[must_use]
69pub fn associated_constant(
70    name: GeneratedToken,
71    kind: Vec<GeneratedToken>,
72    value: Option<Vec<GeneratedToken>>,
73) -> Vec<GeneratedToken> {
74    let mut tokens = vec![
75        GeneratedToken::word("const"),
76        name,
77        GeneratedToken::alone(':'),
78    ];
79    tokens.extend(kind);
80    if let Some(value) = value {
81        tokens.push(GeneratedToken::alone('='));
82        tokens.extend(value);
83    }
84    tokens.push(GeneratedToken::alone(';'));
85    tokens
86}
87
88/// One associated function declaration or definition from an exact signature.
89///
90/// An absent body emits the required signature with a terminal semicolon.
91///
92/// # Errors
93///
94/// Returns [`Overflow`] where a supplied body outgrows the declared generated-token magnitude.
95pub fn associated_function(
96    mut signature: Vec<GeneratedToken>,
97    body: Option<Vec<GeneratedToken>>,
98) -> Result<Vec<GeneratedToken>, Overflow> {
99    if let Some(body) = body {
100        function_item(signature, body)
101    } else {
102        signature.push(GeneratedToken::alone(';'));
103        Ok(signature)
104    }
105}
106
107/// One inherent or trait implementation with exact qualifiers, parameters, target, predicates and items.
108///
109/// An absent trait path emits an inherent implementation.
110/// Qualifiers are emitted exactly before `impl`, so an unsafe implementation remains explicit caller authority.
111///
112/// # Errors
113///
114/// Returns [`Overflow`] where the implementation body outgrows the declared generated-token magnitude.
115pub fn implementation(
116    qualifiers: Vec<GeneratedToken>,
117    parameters: Vec<Vec<GeneratedToken>>,
118    trait_path: Option<Vec<GeneratedToken>>,
119    target: Vec<GeneratedToken>,
120    predicates: Vec<Vec<GeneratedToken>>,
121    items: Vec<GeneratedToken>,
122) -> Result<Vec<GeneratedToken>, Overflow> {
123    let mut tokens = qualifiers;
124    tokens.push(GeneratedToken::word("impl"));
125    tokens.extend(generic_parameters(parameters));
126    if let Some(trait_path) = trait_path {
127        tokens.extend(trait_path);
128        tokens.push(GeneratedToken::word("for"));
129    }
130    tokens.extend(target);
131    tokens.extend(where_clause(predicates));
132    tokens.push(group(GeneratedDelimiter::Brace, items)?);
133    Ok(tokens)
134}
135
136/// Joins exact runs with conventional trait-bound plus punctuation.
137fn plus_many(parts: Vec<Vec<GeneratedToken>>) -> Vec<GeneratedToken> {
138    let mut tokens = Vec::new();
139    for (position, part) in parts.into_iter().enumerate() {
140        if position > 0 {
141            tokens.push(GeneratedToken::alone('+'));
142        }
143        tokens.extend(part);
144    }
145    tokens
146}