1use std::fmt;
8
9use azul_css::{AzString, StringVec, impl_option, impl_option_inner};
10
11#[derive(Debug, Clone, PartialEq, PartialOrd)]
14#[repr(C, u8)]
15pub enum FmtValue {
16 Bool(bool),
17 Uchar(u8),
18 Schar(i8),
19 Ushort(u16),
20 Sshort(i16),
21 Uint(u32),
22 Sint(i32),
23 Ulong(u64),
24 Slong(i64),
25 Isize(isize),
26 Usize(usize),
27 Float(f32),
28 Double(f64),
29 Str(AzString),
30 StrVec(StringVec),
31}
32
33impl strfmt::DisplayStr for FmtValue {
34 fn display_str(&self, f: &mut strfmt::Formatter<'_, '_>) -> strfmt::Result<()> {
35 use strfmt::DisplayStr;
36 match self {
37 Self::Bool(v) => format!("{v}").display_str(f),
38 Self::Uchar(v) => v.display_str(f),
39 Self::Schar(v) => v.display_str(f),
40 Self::Ushort(v) => v.display_str(f),
41 Self::Sshort(v) => v.display_str(f),
42 Self::Uint(v) => v.display_str(f),
43 Self::Sint(v) => v.display_str(f),
44 Self::Ulong(v) => v.display_str(f),
45 Self::Slong(v) => v.display_str(f),
46 Self::Isize(v) => v.display_str(f),
47 Self::Usize(v) => v.display_str(f),
48 Self::Float(v) => v.display_str(f),
49 Self::Double(v) => v.display_str(f),
50 Self::Str(v) => v.as_str().display_str(f),
51 Self::StrVec(sv) => {
52 "[".display_str(f)?;
53 for (i, s) in sv.as_ref().iter().enumerate() {
54 if i != 0 {
55 ", ".display_str(f)?;
56 }
57 s.as_str().display_str(f)?;
58 }
59 "]".display_str(f)?;
60 Ok(())
61 }
62 }
63 }
64}
65
66impl fmt::Display for FmtValue {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 match self {
69 Self::Bool(v) => v.fmt(f),
70 Self::Uchar(v) => v.fmt(f),
71 Self::Schar(v) => v.fmt(f),
72 Self::Ushort(v) => v.fmt(f),
73 Self::Sshort(v) => v.fmt(f),
74 Self::Uint(v) => v.fmt(f),
75 Self::Sint(v) => v.fmt(f),
76 Self::Ulong(v) => v.fmt(f),
77 Self::Slong(v) => v.fmt(f),
78 Self::Isize(v) => v.fmt(f),
79 Self::Usize(v) => v.fmt(f),
80 Self::Float(v) => v.fmt(f),
81 Self::Double(v) => v.fmt(f),
82 Self::Str(v) => v.as_str().fmt(f),
83 Self::StrVec(sv) => {
84 use std::fmt::Debug;
85 let vec: Vec<&str> = sv.as_ref().iter().map(AzString::as_str).collect();
86 vec.fmt(f)
87 }
88 }
89 }
90}
91
92#[derive(Debug, Clone, PartialEq, PartialOrd)]
94#[repr(C)]
95pub struct FmtArg {
96 pub key: AzString,
97 pub value: FmtValue,
98}
99
100azul_css::impl_option!(FmtArg, OptionFmtArg, copy = false, [Debug, Clone, PartialEq, PartialOrd]);
101azul_css::impl_vec!(FmtArg, FmtArgVec, FmtArgVecDestructor, FmtArgVecDestructorType, FmtArgVecSlice, OptionFmtArg);
102azul_css::impl_vec_clone!(FmtArg, FmtArgVec, FmtArgVecDestructor);
103azul_css::impl_vec_debug!(FmtArg, FmtArgVec);
104azul_css::impl_vec_partialeq!(FmtArg, FmtArgVec);
105azul_css::impl_vec_partialord!(FmtArg, FmtArgVec);
106
107#[allow(clippy::needless_pass_by_value)]
111#[must_use] pub fn fmt_string(format: AzString, args: FmtArgVec) -> String {
112 use strfmt::Format;
113 let format_map = args
114 .iter()
115 .map(|a| (a.key.clone().into_library_owned_string(), a.value.clone()))
116 .collect();
117 match format.as_str().format(&format_map) {
118 Ok(o) => o,
119 Err(e) => format!("{e}"),
120 }
121}