1use std::{
8 borrow::Cow,
9 fmt::{Error as FmtError, Write},
10};
11
12use bevy_derive::{Deref, DerefMut};
13use bevy_ecs::prelude::*;
14use bevy_reflect::{Reflectable, prelude::*};
15
16use crate::def::{Locale, LocaleFmt, LocaleResult};
17
18pub trait LocaleTarget: Component {
22 fn update(&mut self, src: &str);
24}
25
26pub(crate) fn localize_target<T: LocaleTarget>(mut query: Query<(&mut T, &LocaleResult), Changed<LocaleResult>>) {
27 for (mut target, src) in &mut query {
28 target.update(src);
29 }
30}
31
32pub trait LocaleArg: 'static + FromReflect + Reflectable + Send + Sync {
35 fn localize_into(&self, locale: &Locale, out: &mut impl Write) -> Result<(), FmtError>;
37
38 #[inline]
41 fn localize(&self, locale: &Locale) -> Result<String, FmtError> {
42 let mut out = String::new();
43 self.localize_into(locale, &mut out)?;
44
45 Ok(out)
46 }
47}
48
49impl LocaleArg for &'static str {
50 #[inline]
51 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
52 out.write_str(self)
53 }
54}
55
56impl LocaleArg for String {
57 #[inline]
58 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
59 out.write_str(self)
60 }
61}
62
63impl LocaleArg for Cow<'static, str> {
64 #[inline]
65 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
66 out.write_str(self)
67 }
68}
69
70impl LocaleArg for u8 {
71 #[inline]
72 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
73 write!(out, "{self}")
74 }
75}
76
77impl LocaleArg for u16 {
78 #[inline]
79 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
80 write!(out, "{self}")
81 }
82}
83
84impl LocaleArg for u32 {
85 #[inline]
86 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
87 write!(out, "{self}")
88 }
89}
90
91impl LocaleArg for u64 {
92 #[inline]
93 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
94 write!(out, "{self}")
95 }
96}
97
98impl LocaleArg for u128 {
99 #[inline]
100 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
101 write!(out, "{self}")
102 }
103}
104
105impl LocaleArg for i8 {
106 #[inline]
107 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
108 write!(out, "{self}")
109 }
110}
111
112impl LocaleArg for i16 {
113 #[inline]
114 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
115 write!(out, "{self}")
116 }
117}
118
119impl LocaleArg for i32 {
120 #[inline]
121 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
122 write!(out, "{self}")
123 }
124}
125
126impl LocaleArg for i64 {
127 #[inline]
128 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
129 write!(out, "{self}")
130 }
131}
132
133impl LocaleArg for i128 {
134 #[inline]
135 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
136 write!(out, "{self}")
137 }
138}
139
140impl LocaleArg for f32 {
141 #[inline]
142 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
143 write!(out, "{self:.2}")
144 }
145}
146
147impl LocaleArg for f64 {
148 #[inline]
149 fn localize_into(&self, _: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
150 write!(out, "{self:.2}")
151 }
152}
153
154#[derive(Component, Reflect, Clone, Deref, DerefMut, Debug)]
160#[reflect(Component, Debug)]
161pub struct LocalizeBy(pub Cow<'static, str>);
162
163impl LocaleArg for LocalizeBy {
164 #[inline]
165 fn localize_into(&self, locale: &Locale, out: &mut impl Write) -> Result<(), FmtError> {
166 let Some(LocaleFmt::Unformatted(res)) = locale.get(&***self) else {
167 return Err(FmtError);
168 };
169
170 write!(out, "{res}")
171 }
172}