use std::borrow::Cow;
use std::fmt;
use std::rc::Rc;
use fluent_bundle::{FluentArgs, FluentValue};
#[derive(Default)]
pub struct Args<'a> {
pub(crate) inner: FluentArgs<'a>,
}
impl<'a> Args<'a> {
pub fn new() -> Self {
Args {
inner: FluentArgs::new(),
}
}
pub fn set(&mut self, name: &'a str, value: impl Into<Value<'a>>) -> &mut Self {
self.inner.set(name, value.into().inner);
self
}
pub fn with(mut self, name: &'a str, value: impl Into<Value<'a>>) -> Self {
self.set(name, value);
self
}
pub(crate) fn has_strings(&self) -> bool {
self.inner
.iter()
.any(|(_, value)| matches!(value, FluentValue::String(_)))
}
}
impl fmt::Debug for Args<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.inner.iter()).finish()
}
}
impl<'a, V> FromIterator<(&'a str, V)> for Args<'a>
where
V: Into<Value<'a>>,
{
fn from_iter<I: IntoIterator<Item = (&'a str, V)>>(iter: I) -> Self {
let mut args = Args::new();
for (name, value) in iter {
args.set(name, value);
}
args
}
}
pub fn args<'a, V>(pairs: impl IntoIterator<Item = (&'a str, V)>) -> Args<'a>
where
V: Into<Value<'a>>,
{
pairs.into_iter().collect()
}
#[macro_export]
#[cfg_attr(phrasebook_docsrs, doc(cfg(feature = "std")))]
macro_rules! args {
() => { $crate::Args::new() };
($($name:tt = $value:expr),+ $(,)?) => {{
let mut args = $crate::Args::new();
$(args.set($crate::__args_name!($name), $value);)+
args
}};
}
#[doc(hidden)]
#[macro_export]
#[cfg_attr(phrasebook_docsrs, doc(cfg(feature = "std")))]
macro_rules! __args_name {
($name:ident) => {
stringify!($name)
};
($name:literal) => {
$name
};
}
#[derive(Clone)]
pub struct Value<'a> {
pub(crate) inner: FluentValue<'a>,
}
impl fmt::Debug for Value<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.inner {
FluentValue::String(s) => fmt::Debug::fmt(s, f),
FluentValue::Number(n) => fmt::Debug::fmt(&n.value, f),
FluentValue::Custom(..) => f.write_str("Custom"),
FluentValue::None => f.write_str("None"),
FluentValue::Error => f.write_str("Error"),
}
}
}
macro_rules! number {
($($ty:ty),* $(,)?) => {
$(
impl From<$ty> for Value<'_> {
#[inline]
fn from(value: $ty) -> Self {
Value { inner: FluentValue::from(value) }
}
}
impl From<&$ty> for Value<'_> {
#[inline]
fn from(value: &$ty) -> Self {
Value { inner: FluentValue::from(*value) }
}
}
)*
};
}
number!(
i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64
);
impl<'a> From<&'a str> for Value<'a> {
#[inline]
fn from(value: &'a str) -> Self {
Value {
inner: FluentValue::from(value),
}
}
}
impl<'a> From<&'a String> for Value<'a> {
#[inline]
fn from(value: &'a String) -> Self {
Value {
inner: FluentValue::from(value.as_str()),
}
}
}
impl From<String> for Value<'_> {
#[inline]
fn from(value: String) -> Self {
Value {
inner: FluentValue::from(value),
}
}
}
impl<'a> From<Cow<'a, str>> for Value<'a> {
#[inline]
fn from(value: Cow<'a, str>) -> Self {
Value {
inner: FluentValue::String(value),
}
}
}
impl From<Rc<str>> for Value<'_> {
#[inline]
fn from(value: Rc<str>) -> Self {
Value {
inner: FluentValue::from(String::from(&*value)),
}
}
}
impl<'a> From<&'a Rc<str>> for Value<'a> {
#[inline]
fn from(value: &'a Rc<str>) -> Self {
Value {
inner: FluentValue::from(&**value),
}
}
}