use crate::label::humanize;
use crate::message::Recorded;
use crate::syntax::{Expression, Position};
#[derive(Clone, Debug)]
#[cfg_attr(
not(feature = "parse"),
expect(dead_code, reason = "positions locate what the template check reports")
)]
pub(crate) enum Call {
Translate {
key: String,
counted: Option<CountedKeys>,
arguments: Vec<Argument>,
recorded: Option<Recorded>,
position: Position,
},
Format {
format: Format,
value: Expression,
position: Position,
},
Label {
key: String,
humanized: String,
position: Position,
},
}
#[derive(Clone, Debug)]
pub(crate) struct CountedKeys {
pub one: String,
pub other: String,
}
impl Call {
pub(crate) fn translate(
key: String,
arguments: Vec<Argument>,
position: Position,
recorded: Option<Recorded>,
) -> Self {
let counted = arguments
.iter()
.any(|argument| argument.name == "count")
.then(|| CountedKeys {
one: format!("{key}.one"),
other: format!("{key}.other"),
});
Self::Translate {
key,
counted,
arguments,
recorded,
position,
}
}
#[cfg(feature = "parse")]
pub(crate) fn date(value: Expression, position: Position) -> Self {
Self::Format {
format: Format::Date,
value,
position,
}
}
}
#[derive(Clone, Debug)]
pub(crate) struct Argument {
pub name: String,
pub value: Expression,
}
impl Argument {
pub(crate) fn plain_value(&self) -> &Expression {
if let Expression::Call(call) = &self.value
&& let Call::Format {
format: Format::Number,
value,
..
} = &**call
{
return value;
}
&self.value
}
}
#[derive(Clone, Copy, Debug)]
pub(crate) enum Format {
Number,
Money,
Date,
}
pub(crate) fn label(name: &str, position: Position) -> Expression {
Expression::Call(Box::new(Call::Label {
key: format!("label.{name}"),
humanized: humanize(name),
position,
}))
}
#[cfg(feature = "parse")]
impl Call {
pub(crate) fn arguments_mut(&mut self) -> impl Iterator<Item = &mut Expression> {
let (arguments, value): (&mut [Argument], Option<&mut Expression>) = match self {
Self::Translate { arguments, .. } => (arguments, None),
Self::Format { value, .. } => (&mut [], Some(value)),
Self::Label { .. } => (&mut [], None),
};
arguments
.iter_mut()
.map(|argument| &mut argument.value)
.chain(value)
}
pub(crate) fn recorded_mut(&mut self) -> Option<(&str, &mut Option<Recorded>)> {
match self {
Self::Translate { key, recorded, .. } => Some((key, recorded)),
Self::Format { .. } | Self::Label { .. } => None,
}
}
pub(crate) fn position(&self) -> Position {
match self {
Self::Translate { position, .. }
| Self::Format { position, .. }
| Self::Label { position, .. } => *position,
}
}
}