use crate::bounded::Overflow;
use crate::descriptor::DirectBinding;
use crate::descriptor::vocabulary::HarnessWord;
use crate::token::{
GeneratedDelimiter, GeneratedToken, absolute_path, associated_function, attribute, comma_many,
documentation, function_signature, group, implementation, result_type, typed_parameter,
};
pub(crate) fn direct_path(
binding: &DirectBinding,
destination: &[&str],
into: &mut Vec<GeneratedToken>,
) {
let segments = binding
.segments()
.iter()
.map(String::as_str)
.chain(destination.iter().copied())
.collect::<Vec<_>>();
into.extend(absolute_path(&segments));
}
#[must_use]
pub(crate) fn owned_direct_path(
binding: &DirectBinding,
destination: &[&str],
) -> Vec<GeneratedToken> {
let mut tokens = Vec::new();
direct_path(binding, destination, &mut tokens);
tokens
}
#[must_use]
pub(crate) fn row_metavariable(lens: &str, seat: HarnessWord) -> String {
let seat = seat.spelling();
format!("{lens}_{seat}")
}
pub(crate) fn doc_attribute(text: &str, into: &mut Vec<GeneratedToken>) -> Result<(), Overflow> {
into.extend(documentation(text)?);
Ok(())
}
pub(crate) fn derive_attribute(
traits: &[&str],
into: &mut Vec<GeneratedToken>,
) -> Result<(), Overflow> {
let listed = comma_many(
traits
.iter()
.map(|name| vec![GeneratedToken::word(name)])
.collect(),
);
into.extend(attribute(vec![
GeneratedToken::word("derive"),
group(GeneratedDelimiter::Parenthesis, listed)?,
])?);
Ok(())
}
pub(crate) fn from_impl(
source: Vec<GeneratedToken>,
target: &str,
arm: &str,
into: &mut Vec<GeneratedToken>,
) -> Result<(), Overflow> {
let mut trait_path = absolute_path(&["core", "convert", "From"]);
trait_path.push(GeneratedToken::alone('<'));
trait_path.extend(source.iter().cloned());
trait_path.push(GeneratedToken::alone('>'));
let signature = function_signature(
Vec::new(),
GeneratedToken::word("from"),
vec![typed_parameter(
vec![GeneratedToken::word("refusal")],
source,
)],
Vec::new(),
Some(vec![GeneratedToken::word("Self")]),
Vec::new(),
)?;
let body = vec![
GeneratedToken::word("Self"),
GeneratedToken::joint(':'),
GeneratedToken::alone(':'),
GeneratedToken::word(arm),
GeneratedToken::group(
GeneratedDelimiter::Parenthesis,
vec![GeneratedToken::word("refusal")],
)?,
];
let road = associated_function(signature, Some(body))?;
into.extend(implementation(
Vec::new(),
Vec::new(),
Some(trait_path),
vec![GeneratedToken::word(target)],
Vec::new(),
road,
)?);
Ok(())
}
pub(crate) fn fallible_return(
ok_seat: Vec<GeneratedToken>,
fault: &str,
into: &mut Vec<GeneratedToken>,
) {
into.push(GeneratedToken::joint('-'));
into.push(GeneratedToken::alone('>'));
into.extend(result_type(ok_seat, vec![GeneratedToken::word(fault)]));
}