Skip to main content

macroonz_compiler/token/generation/
behavior.rs

1//! Conventional Rust behavior shells assembled from exact generated-token runs.
2//!
3//! These operations own fixed function, receiver and match punctuation only.
4//! The caller owns every name, qualifier, parameter, result, predicate, pattern, guard, body, effect and semantic meaning.
5
6use super::compose::{absolute_path, comma_many, group};
7use super::items::{generic_parameters, where_clause};
8use super::{GeneratedDelimiter, GeneratedToken};
9use crate::bounded::Overflow;
10
11/// One typed parameter `pattern: kind`.
12#[must_use]
13pub fn typed_parameter(
14    mut pattern: Vec<GeneratedToken>,
15    kind: Vec<GeneratedToken>,
16) -> Vec<GeneratedToken> {
17    pattern.push(GeneratedToken::alone(':'));
18    pattern.extend(kind);
19    pattern
20}
21
22/// The conventional consuming receiver `self`.
23#[must_use]
24pub fn consuming_receiver() -> Vec<GeneratedToken> {
25    vec![GeneratedToken::word("self")]
26}
27
28/// The conventional shared receiver `&'a self`, with an empty lifetime run producing `&self`.
29#[must_use]
30pub fn shared_receiver(lifetime: Vec<GeneratedToken>) -> Vec<GeneratedToken> {
31    let mut tokens = vec![GeneratedToken::alone('&')];
32    tokens.extend(lifetime);
33    tokens.push(GeneratedToken::word("self"));
34    tokens
35}
36
37/// The conventional exclusive receiver `&'a mut self`, with an empty lifetime run producing `&mut self`.
38#[must_use]
39pub fn exclusive_receiver(lifetime: Vec<GeneratedToken>) -> Vec<GeneratedToken> {
40    let mut tokens = vec![GeneratedToken::alone('&')];
41    tokens.extend(lifetime);
42    tokens.extend([GeneratedToken::word("mut"), GeneratedToken::word("self")]);
43    tokens
44}
45
46/// The conventional pinned receiver `self: ::core::pin::Pin<&'a mut Self>`.
47#[must_use]
48pub fn pinned_receiver(lifetime: Vec<GeneratedToken>) -> Vec<GeneratedToken> {
49    let mut kind = absolute_path(&["core", "pin", "Pin"]);
50    kind.extend([GeneratedToken::alone('<'), GeneratedToken::alone('&')]);
51    kind.extend(lifetime);
52    kind.extend([
53        GeneratedToken::word("mut"),
54        GeneratedToken::word("Self"),
55        GeneratedToken::alone('>'),
56    ]);
57    typed_parameter(vec![GeneratedToken::word("self")], kind)
58}
59
60/// One exact function signature without visibility, attributes, body or terminal semicolon.
61///
62/// Qualifiers are emitted exactly before `fn`, so the caller retains `const`, `async`, `unsafe`, or external-ABI authority.
63/// An absent result emits no thin arrow, while a present result is preserved exactly.
64///
65/// # Errors
66///
67/// Returns [`Overflow`] where the parameter group outgrows the declared generated-token magnitude.
68pub fn function_signature(
69    qualifiers: Vec<GeneratedToken>,
70    name: GeneratedToken,
71    parameters: Vec<Vec<GeneratedToken>>,
72    generics: Vec<Vec<GeneratedToken>>,
73    result: Option<Vec<GeneratedToken>>,
74    predicates: Vec<Vec<GeneratedToken>>,
75) -> Result<Vec<GeneratedToken>, Overflow> {
76    let mut tokens = qualifiers;
77    tokens.extend([GeneratedToken::word("fn"), name]);
78    tokens.extend(generic_parameters(generics));
79    tokens.push(group(
80        GeneratedDelimiter::Parenthesis,
81        comma_many(parameters),
82    )?);
83    if let Some(result) = result {
84        tokens.extend([GeneratedToken::joint('-'), GeneratedToken::alone('>')]);
85        tokens.extend(result);
86    }
87    tokens.extend(where_clause(predicates));
88    Ok(tokens)
89}
90
91/// One function or method item from an exact signature and exact body.
92///
93/// # Errors
94///
95/// Returns [`Overflow`] where the body outgrows the declared generated-token magnitude.
96pub fn function_item(
97    mut signature: Vec<GeneratedToken>,
98    body: Vec<GeneratedToken>,
99) -> Result<Vec<GeneratedToken>, Overflow> {
100    signature.push(group(GeneratedDelimiter::Brace, body)?);
101    Ok(signature)
102}
103
104/// One conventional `fn name(parameters) -> result { body }` item.
105///
106/// The visibility is the caller's and is written before this, so one operation spells a private function, a `pub` one, and a `pub(crate)` one.
107/// This narrow convenience accepts one flattened parameter run and delegates all function framing to [`function_signature`] and [`function_item`].
108///
109/// # Errors
110///
111/// Returns [`Overflow`] where the parameter list or body outgrows the declared generated-token magnitude.
112pub fn function(
113    name: &str,
114    parameters: Vec<GeneratedToken>,
115    result: Vec<GeneratedToken>,
116    body: Vec<GeneratedToken>,
117) -> Result<Vec<GeneratedToken>, Overflow> {
118    let signature = function_signature(
119        Vec::new(),
120        GeneratedToken::word(name),
121        vec![parameters],
122        Vec::new(),
123        Some(result),
124        Vec::new(),
125    )?;
126    function_item(signature, body)
127}
128
129/// One match arm with an optional exact guard and a trailing comma.
130#[must_use]
131pub fn match_arm(
132    mut pattern: Vec<GeneratedToken>,
133    guard: Option<Vec<GeneratedToken>>,
134    body: Vec<GeneratedToken>,
135) -> Vec<GeneratedToken> {
136    if let Some(guard) = guard {
137        pattern.push(GeneratedToken::word("if"));
138        pattern.extend(guard);
139    }
140    pattern.extend([GeneratedToken::joint('='), GeneratedToken::alone('>')]);
141    pattern.extend(body);
142    pattern.push(GeneratedToken::alone(','));
143    pattern
144}
145
146/// One match expression over exact subject and arm runs.
147///
148/// # Errors
149///
150/// Returns [`Overflow`] where the arm group outgrows the declared generated-token magnitude.
151pub fn match_expression(
152    mut subject: Vec<GeneratedToken>,
153    arms: Vec<Vec<GeneratedToken>>,
154) -> Result<Vec<GeneratedToken>, Overflow> {
155    let mut tokens = vec![GeneratedToken::word("match")];
156    tokens.append(&mut subject);
157    tokens.push(group(
158        GeneratedDelimiter::Brace,
159        arms.into_iter().flatten().collect(),
160    )?);
161    Ok(tokens)
162}