use super::compose::{comma_many, group};
use super::{GeneratedDelimiter, GeneratedToken};
use crate::bounded::Overflow;
#[must_use]
pub fn decorated(
attributes: Vec<Vec<GeneratedToken>>,
visibility: Vec<GeneratedToken>,
item: Vec<GeneratedToken>,
) -> Vec<GeneratedToken> {
let mut tokens = attributes.into_iter().flatten().collect::<Vec<_>>();
tokens.extend(visibility);
tokens.extend(item);
tokens
}
pub fn inline_module(
name: GeneratedToken,
items: Vec<GeneratedToken>,
) -> Result<Vec<GeneratedToken>, Overflow> {
Ok(vec![
GeneratedToken::word("mod"),
name,
group(GeneratedDelimiter::Brace, items)?,
])
}
#[must_use]
pub fn use_item(path: Vec<GeneratedToken>, alias: Option<GeneratedToken>) -> Vec<GeneratedToken> {
let mut tokens = vec![GeneratedToken::word("use")];
tokens.extend(path);
if let Some(alias) = alias {
tokens.extend([GeneratedToken::word("as"), alias]);
}
tokens.push(GeneratedToken::alone(';'));
tokens
}
#[must_use]
pub fn generic_parameters(parameters: Vec<Vec<GeneratedToken>>) -> Vec<GeneratedToken> {
if parameters.is_empty() {
Vec::new()
} else {
let mut tokens = vec![GeneratedToken::alone('<')];
tokens.extend(comma_many(parameters));
tokens.push(GeneratedToken::alone('>'));
tokens
}
}
#[must_use]
pub fn where_clause(predicates: Vec<Vec<GeneratedToken>>) -> Vec<GeneratedToken> {
if predicates.is_empty() {
Vec::new()
} else {
let mut tokens = vec![GeneratedToken::word("where")];
tokens.extend(comma_many(predicates));
tokens
}
}
#[must_use]
pub fn type_alias(
name: GeneratedToken,
parameters: Vec<Vec<GeneratedToken>>,
value: Vec<GeneratedToken>,
predicates: Vec<Vec<GeneratedToken>>,
) -> Vec<GeneratedToken> {
let mut tokens = vec![GeneratedToken::word("type"), name];
tokens.extend(generic_parameters(parameters));
tokens.push(GeneratedToken::alone('='));
tokens.extend(value);
tokens.extend(where_clause(predicates));
tokens.push(GeneratedToken::alone(';'));
tokens
}
#[must_use]
pub fn unit_struct(
name: GeneratedToken,
parameters: Vec<Vec<GeneratedToken>>,
predicates: Vec<Vec<GeneratedToken>>,
) -> Vec<GeneratedToken> {
let mut tokens = item_head("struct", name, parameters);
tokens.extend(where_clause(predicates));
tokens.push(GeneratedToken::alone(';'));
tokens
}
pub fn tuple_struct(
name: GeneratedToken,
parameters: Vec<Vec<GeneratedToken>>,
fields: Vec<Vec<GeneratedToken>>,
predicates: Vec<Vec<GeneratedToken>>,
) -> Result<Vec<GeneratedToken>, Overflow> {
let mut tokens = item_head("struct", name, parameters);
tokens.push(group(GeneratedDelimiter::Parenthesis, comma_many(fields))?);
tokens.extend(where_clause(predicates));
tokens.push(GeneratedToken::alone(';'));
Ok(tokens)
}
pub fn named_struct(
name: GeneratedToken,
parameters: Vec<Vec<GeneratedToken>>,
predicates: Vec<Vec<GeneratedToken>>,
fields: Vec<Vec<GeneratedToken>>,
) -> Result<Vec<GeneratedToken>, Overflow> {
let mut tokens = item_head("struct", name, parameters);
tokens.extend(where_clause(predicates));
tokens.push(group(GeneratedDelimiter::Brace, comma_many(fields))?);
Ok(tokens)
}
#[must_use]
pub fn named_field(name: GeneratedToken, kind: Vec<GeneratedToken>) -> Vec<GeneratedToken> {
let mut tokens = vec![name, GeneratedToken::alone(':')];
tokens.extend(kind);
tokens
}
pub fn enumeration(
name: GeneratedToken,
parameters: Vec<Vec<GeneratedToken>>,
predicates: Vec<Vec<GeneratedToken>>,
variants: Vec<Vec<GeneratedToken>>,
) -> Result<Vec<GeneratedToken>, Overflow> {
let mut tokens = item_head("enum", name, parameters);
tokens.extend(where_clause(predicates));
tokens.push(group(GeneratedDelimiter::Brace, comma_many(variants))?);
Ok(tokens)
}
#[must_use]
pub fn unit_variant(name: GeneratedToken) -> Vec<GeneratedToken> {
vec![name]
}
pub fn tuple_variant(
name: GeneratedToken,
fields: Vec<Vec<GeneratedToken>>,
) -> Result<Vec<GeneratedToken>, Overflow> {
Ok(vec![
name,
group(GeneratedDelimiter::Parenthesis, comma_many(fields))?,
])
}
pub fn named_variant(
name: GeneratedToken,
fields: Vec<Vec<GeneratedToken>>,
) -> Result<Vec<GeneratedToken>, Overflow> {
Ok(vec![
name,
group(GeneratedDelimiter::Brace, comma_many(fields))?,
])
}
fn item_head(
keyword: &str,
name: GeneratedToken,
parameters: Vec<Vec<GeneratedToken>>,
) -> Vec<GeneratedToken> {
let mut tokens = vec![GeneratedToken::word(keyword), name];
tokens.extend(generic_parameters(parameters));
tokens
}