use super::behavior::function_item;
use super::compose::group;
use super::items::{generic_parameters, where_clause};
use super::{GeneratedDelimiter, GeneratedToken};
use crate::bounded::Overflow;
pub fn trait_declaration(
qualifiers: Vec<GeneratedToken>,
name: GeneratedToken,
parameters: Vec<Vec<GeneratedToken>>,
supertraits: Vec<Vec<GeneratedToken>>,
predicates: Vec<Vec<GeneratedToken>>,
items: Vec<GeneratedToken>,
) -> Result<Vec<GeneratedToken>, Overflow> {
let mut tokens = qualifiers;
tokens.extend([GeneratedToken::word("trait"), name]);
tokens.extend(generic_parameters(parameters));
if !supertraits.is_empty() {
tokens.push(GeneratedToken::alone(':'));
tokens.extend(plus_many(supertraits));
}
tokens.extend(where_clause(predicates));
tokens.push(group(GeneratedDelimiter::Brace, items)?);
Ok(tokens)
}
#[must_use]
pub fn associated_type(
name: GeneratedToken,
parameters: Vec<Vec<GeneratedToken>>,
bounds: Vec<Vec<GeneratedToken>>,
value: Option<Vec<GeneratedToken>>,
predicates: Vec<Vec<GeneratedToken>>,
) -> Vec<GeneratedToken> {
let mut tokens = vec![GeneratedToken::word("type"), name];
tokens.extend(generic_parameters(parameters));
if !bounds.is_empty() {
tokens.push(GeneratedToken::alone(':'));
tokens.extend(plus_many(bounds));
}
if let Some(value) = value {
tokens.push(GeneratedToken::alone('='));
tokens.extend(value);
}
tokens.extend(where_clause(predicates));
tokens.push(GeneratedToken::alone(';'));
tokens
}
#[must_use]
pub fn associated_constant(
name: GeneratedToken,
kind: Vec<GeneratedToken>,
value: Option<Vec<GeneratedToken>>,
) -> Vec<GeneratedToken> {
let mut tokens = vec![
GeneratedToken::word("const"),
name,
GeneratedToken::alone(':'),
];
tokens.extend(kind);
if let Some(value) = value {
tokens.push(GeneratedToken::alone('='));
tokens.extend(value);
}
tokens.push(GeneratedToken::alone(';'));
tokens
}
pub fn associated_function(
mut signature: Vec<GeneratedToken>,
body: Option<Vec<GeneratedToken>>,
) -> Result<Vec<GeneratedToken>, Overflow> {
if let Some(body) = body {
function_item(signature, body)
} else {
signature.push(GeneratedToken::alone(';'));
Ok(signature)
}
}
pub fn implementation(
qualifiers: Vec<GeneratedToken>,
parameters: Vec<Vec<GeneratedToken>>,
trait_path: Option<Vec<GeneratedToken>>,
target: Vec<GeneratedToken>,
predicates: Vec<Vec<GeneratedToken>>,
items: Vec<GeneratedToken>,
) -> Result<Vec<GeneratedToken>, Overflow> {
let mut tokens = qualifiers;
tokens.push(GeneratedToken::word("impl"));
tokens.extend(generic_parameters(parameters));
if let Some(trait_path) = trait_path {
tokens.extend(trait_path);
tokens.push(GeneratedToken::word("for"));
}
tokens.extend(target);
tokens.extend(where_clause(predicates));
tokens.push(group(GeneratedDelimiter::Brace, items)?);
Ok(tokens)
}
fn plus_many(parts: Vec<Vec<GeneratedToken>>) -> Vec<GeneratedToken> {
let mut tokens = Vec::new();
for (position, part) in parts.into_iter().enumerate() {
if position > 0 {
tokens.push(GeneratedToken::alone('+'));
}
tokens.extend(part);
}
tokens
}