use crate::bounded::Overflow;
use crate::descriptor::DirectBinding;
use crate::token::{GeneratedDelimiter, GeneratedToken};
pub(crate) fn absolute_path(segments: &[&str], into: &mut Vec<GeneratedToken>) {
for segment in segments {
into.push(GeneratedToken::joint(':'));
into.push(GeneratedToken::alone(':'));
into.push(GeneratedToken::word(segment));
}
}
pub(crate) fn direct_path(
binding: &DirectBinding,
destination: &[&str],
into: &mut Vec<GeneratedToken>,
) {
let mut segments = binding.segments().iter().map(String::as_str);
if let Some(root) = segments.next() {
into.push(GeneratedToken::joint(':'));
into.push(GeneratedToken::alone(':'));
into.push(GeneratedToken::word(root));
}
for segment in segments.chain(destination.iter().copied()) {
into.push(GeneratedToken::joint(':'));
into.push(GeneratedToken::alone(':'));
into.push(GeneratedToken::word(segment));
}
}
pub(crate) fn doc_attribute(text: &str, into: &mut Vec<GeneratedToken>) -> Result<(), Overflow> {
into.push(GeneratedToken::alone('#'));
into.push(GeneratedToken::group(
GeneratedDelimiter::Bracket,
vec![
GeneratedToken::word("doc"),
GeneratedToken::alone('='),
GeneratedToken::text(text),
],
)?);
Ok(())
}
pub(crate) fn derive_attribute(
traits: &[&str],
into: &mut Vec<GeneratedToken>,
) -> Result<(), Overflow> {
let mut listed = Vec::new();
for (position, name) in traits.iter().enumerate() {
if position > 0 {
listed.push(GeneratedToken::alone(','));
}
listed.push(GeneratedToken::word(name));
}
into.push(GeneratedToken::alone('#'));
into.push(GeneratedToken::group(
GeneratedDelimiter::Bracket,
vec![
GeneratedToken::word("derive"),
GeneratedToken::group(GeneratedDelimiter::Parenthesis, listed)?,
],
)?);
Ok(())
}
pub(crate) fn from_impl(
source: Vec<GeneratedToken>,
target: &str,
arm: &str,
into: &mut Vec<GeneratedToken>,
) -> Result<(), Overflow> {
into.push(GeneratedToken::word("impl"));
absolute_path(&["core", "convert", "From"], into);
into.push(GeneratedToken::alone('<'));
into.extend(source.iter().cloned());
into.push(GeneratedToken::alone('>'));
into.push(GeneratedToken::word("for"));
into.push(GeneratedToken::word(target));
let mut body = vec![GeneratedToken::word("fn"), GeneratedToken::word("from")];
let mut parameter = vec![GeneratedToken::word("refusal"), GeneratedToken::alone(':')];
parameter.extend(source);
body.push(GeneratedToken::group(
GeneratedDelimiter::Parenthesis,
parameter,
)?);
body.push(GeneratedToken::joint('-'));
body.push(GeneratedToken::alone('>'));
body.push(GeneratedToken::word("Self"));
body.push(GeneratedToken::group(
GeneratedDelimiter::Brace,
vec![
GeneratedToken::word("Self"),
GeneratedToken::joint(':'),
GeneratedToken::alone(':'),
GeneratedToken::word(arm),
GeneratedToken::group(
GeneratedDelimiter::Parenthesis,
vec![GeneratedToken::word("refusal")],
)?,
],
)?);
into.push(GeneratedToken::group(GeneratedDelimiter::Brace, body)?);
Ok(())
}
pub(crate) fn fallible_return(
ok_seat: Vec<GeneratedToken>,
fault: &str,
into: &mut Vec<GeneratedToken>,
) {
into.push(GeneratedToken::joint('-'));
into.push(GeneratedToken::alone('>'));
absolute_path(&["core", "result", "Result"], into);
into.push(GeneratedToken::alone('<'));
into.extend(ok_seat);
into.push(GeneratedToken::alone(','));
into.push(GeneratedToken::word(fault));
into.push(GeneratedToken::alone('>'));
}