1use std::{
2 collections::HashMap,
3 fmt::{self, Display, Write},
4};
5
6use serde::ser;
7
8#[derive(Debug, Clone, Copy)]
9pub enum ArgType {
10 Bool,
11 Value,
12}
13
14#[derive(Debug, Clone)]
15pub struct CliArgsSet {
16 language: &'static str,
17
18 args: HashMap<&'static str, (String, ArgType)>,
22}
23
24impl CliArgsSet {
25 pub fn iter(&self) -> impl Iterator<Item = ArgSpec<'_>> + '_ {
26 self.args
27 .iter()
28 .map(|(&key, &(ref full_key, arg_type))| ArgSpec {
29 key,
30 full_key: full_key.as_str(),
31 arg_type,
32 })
33 }
34
35 pub const fn language(&self) -> &'static str {
36 self.language
37 }
38
39 pub fn contains_key(&self, key: &str) -> bool {
40 self.args.contains_key(key)
41 }
42}
43
44pub struct ArgSpec<'a> {
45 pub key: &'static str,
48
49 pub full_key: &'a str,
52
53 pub arg_type: ArgType,
57}
58
59#[derive(thiserror::Error, Debug, Clone)]
60#[error("config container must be a struct type")]
61pub struct ArgsSetError;
62
63impl ser::Error for ArgsSetError {
64 fn custom<T>(_msg: T) -> Self
65 where
66 T: std::fmt::Display,
67 {
68 Self
69 }
70}
71
72pub struct ArgsSetSerializer {
73 args: CliArgsSet,
74}
75
76impl ArgsSetSerializer {
77 pub fn new(language: &'static str) -> Self {
78 Self {
79 args: CliArgsSet {
80 language,
81 args: HashMap::new(),
82 },
83 }
84 }
85}
86
87impl ser::Serializer for ArgsSetSerializer {
88 type Ok = CliArgsSet;
89 type Error = ArgsSetError;
90
91 type SerializeSeq = ser::Impossible<Self::Ok, Self::Error>;
92 type SerializeTuple = ser::Impossible<Self::Ok, Self::Error>;
93 type SerializeTupleStruct = ser::Impossible<Self::Ok, Self::Error>;
94 type SerializeTupleVariant = ser::Impossible<Self::Ok, Self::Error>;
95 type SerializeStructVariant = ser::Impossible<Self::Ok, Self::Error>;
96 type SerializeMap = ser::Impossible<Self::Ok, Self::Error>;
97
98 type SerializeStruct = Self;
99
100 fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
101 Err(ArgsSetError)
102 }
103
104 fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
105 Err(ArgsSetError)
106 }
107
108 fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
109 Err(ArgsSetError)
110 }
111
112 fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
113 Err(ArgsSetError)
114 }
115
116 fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
117 Err(ArgsSetError)
118 }
119
120 fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
121 Err(ArgsSetError)
122 }
123
124 fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
125 Err(ArgsSetError)
126 }
127
128 fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
129 Err(ArgsSetError)
130 }
131
132 fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
133 Err(ArgsSetError)
134 }
135
136 fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
137 Err(ArgsSetError)
138 }
139
140 fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
141 Err(ArgsSetError)
142 }
143
144 fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
145 Err(ArgsSetError)
146 }
147
148 fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
149 Err(ArgsSetError)
150 }
151
152 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
153 Err(ArgsSetError)
154 }
155
156 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
157 Err(ArgsSetError)
158 }
159
160 fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
161 where
162 T: ?Sized + ser::Serialize,
163 {
164 Err(ArgsSetError)
165 }
166
167 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
168 Err(ArgsSetError)
169 }
170
171 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
172 Err(ArgsSetError)
173 }
174
175 fn serialize_unit_variant(
176 self,
177 _name: &'static str,
178 _variant_index: u32,
179 _variant: &'static str,
180 ) -> Result<Self::Ok, Self::Error> {
181 Err(ArgsSetError)
182 }
183
184 fn serialize_newtype_struct<T>(
185 self,
186 _name: &'static str,
187 value: &T,
188 ) -> Result<Self::Ok, Self::Error>
189 where
190 T: ?Sized + ser::Serialize,
191 {
192 value.serialize(self)
193 }
194
195 fn serialize_newtype_variant<T>(
196 self,
197 _name: &'static str,
198 _variant_index: u32,
199 _variant: &'static str,
200 _value: &T,
201 ) -> Result<Self::Ok, Self::Error>
202 where
203 T: ?Sized + ser::Serialize,
204 {
205 Err(ArgsSetError)
206 }
207
208 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
209 Err(ArgsSetError)
210 }
211
212 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
213 Err(ArgsSetError)
214 }
215
216 fn serialize_tuple_struct(
217 self,
218 _name: &'static str,
219 _len: usize,
220 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
221 Err(ArgsSetError)
222 }
223
224 fn serialize_tuple_variant(
225 self,
226 _name: &'static str,
227 _variant_index: u32,
228 _variant: &'static str,
229 _len: usize,
230 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
231 Err(ArgsSetError)
232 }
233
234 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
235 Err(ArgsSetError)
236 }
237
238 fn serialize_struct(
239 self,
240 _name: &'static str,
241 _len: usize,
242 ) -> Result<Self::SerializeStruct, Self::Error> {
243 Ok(self)
244 }
245
246 fn serialize_struct_variant(
247 self,
248 _name: &'static str,
249 _variant_index: u32,
250 _variant: &'static str,
251 _len: usize,
252 ) -> Result<Self::SerializeStructVariant, Self::Error> {
253 Err(ArgsSetError)
254 }
255}
256
257impl ser::SerializeStruct for ArgsSetSerializer {
258 type Ok = CliArgsSet;
259 type Error = ArgsSetError;
260
261 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
262 where
263 T: ?Sized + ser::Serialize,
264 {
265 if let Some(arg_type) = value.serialize(ArgsSetFieldSerializer)? {
267 let full_key = format!(
268 "{language}-{key}",
269 language = self.args.language,
270 key = UnderscoreToHyphen(key)
271 );
272
273 self.args.args.insert(key, (full_key, arg_type));
274 }
275
276 Ok(())
277 }
278
279 fn end(self) -> Result<Self::Ok, Self::Error> {
280 Ok(self.args)
281 }
282}
283
284struct UnderscoreToHyphen<'a>(&'a str);
285
286impl Display for UnderscoreToHyphen<'_> {
287 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
288 let mut chunks = self.0.split('_');
289
290 match chunks.next() {
291 None => Ok(()),
292 Some(first) => {
293 f.write_str(first)?;
294 chunks.try_for_each(|chunk| {
295 f.write_char('-')?;
296 f.write_str(chunk)
297 })
298 }
299 }
300 }
301}
302
303struct ArgsSetFieldSerializer;
307
308impl ser::Serializer for ArgsSetFieldSerializer {
309 type Ok = Option<ArgType>;
310 type Error = ArgsSetError;
311
312 type SerializeSeq = NoOpSubSerializer;
314 type SerializeTuple = NoOpSubSerializer;
315 type SerializeTupleStruct = NoOpSubSerializer;
316 type SerializeTupleVariant = NoOpSubSerializer;
317 type SerializeMap = NoOpSubSerializer;
318 type SerializeStruct = NoOpSubSerializer;
319 type SerializeStructVariant = NoOpSubSerializer;
320
321 fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
322 Ok(Some(ArgType::Bool))
323 }
324
325 fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
326 Ok(Some(ArgType::Value))
327 }
328
329 fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
330 Ok(Some(ArgType::Value))
331 }
332
333 fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
334 Ok(Some(ArgType::Value))
335 }
336
337 fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
338 Ok(Some(ArgType::Value))
339 }
340
341 fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
342 Ok(Some(ArgType::Value))
343 }
344
345 fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
346 Ok(Some(ArgType::Value))
347 }
348
349 fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
350 Ok(Some(ArgType::Value))
351 }
352
353 fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
354 Ok(Some(ArgType::Value))
355 }
356
357 fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
358 Ok(Some(ArgType::Value))
359 }
360
361 fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
362 Ok(Some(ArgType::Value))
363 }
364
365 fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
366 Ok(Some(ArgType::Value))
367 }
368
369 fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
370 Ok(Some(ArgType::Value))
371 }
372
373 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
374 Ok(Some(ArgType::Value))
375 }
376
377 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
378 Ok(Some(ArgType::Value))
379 }
380
381 fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
382 where
383 T: ?Sized + ser::Serialize,
384 {
385 Ok(Some(ArgType::Value))
386 }
387
388 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
389 Ok(None)
390 }
391
392 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
393 Ok(None)
394 }
395
396 fn serialize_unit_variant(
397 self,
398 _name: &'static str,
399 _variant_index: u32,
400 _variant: &'static str,
401 ) -> Result<Self::Ok, Self::Error> {
402 Ok(Some(ArgType::Value))
403 }
404
405 fn serialize_newtype_struct<T>(
406 self,
407 _name: &'static str,
408 value: &T,
409 ) -> Result<Self::Ok, Self::Error>
410 where
411 T: ?Sized + ser::Serialize,
412 {
413 value.serialize(self)
414 }
415
416 fn serialize_newtype_variant<T>(
417 self,
418 _name: &'static str,
419 _variant_index: u32,
420 _variant: &'static str,
421 _value: &T,
422 ) -> Result<Self::Ok, Self::Error>
423 where
424 T: ?Sized + ser::Serialize,
425 {
426 Ok(None)
427 }
428
429 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
430 Ok(NoOpSubSerializer)
431 }
432
433 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
434 Ok(NoOpSubSerializer)
435 }
436
437 fn serialize_tuple_struct(
438 self,
439 _name: &'static str,
440 _len: usize,
441 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
442 Ok(NoOpSubSerializer)
443 }
444
445 fn serialize_tuple_variant(
446 self,
447 _name: &'static str,
448 _variant_index: u32,
449 _variant: &'static str,
450 _len: usize,
451 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
452 Ok(NoOpSubSerializer)
453 }
454
455 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
456 Ok(NoOpSubSerializer)
457 }
458
459 fn serialize_struct(
460 self,
461 _name: &'static str,
462 _len: usize,
463 ) -> Result<Self::SerializeStruct, Self::Error> {
464 Ok(NoOpSubSerializer)
465 }
466
467 fn serialize_struct_variant(
468 self,
469 _name: &'static str,
470 _variant_index: u32,
471 _variant: &'static str,
472 _len: usize,
473 ) -> Result<Self::SerializeStructVariant, Self::Error> {
474 Ok(NoOpSubSerializer)
475 }
476}
477
478struct NoOpSubSerializer;
479
480impl ser::SerializeSeq for NoOpSubSerializer {
481 type Ok = Option<ArgType>;
482 type Error = ArgsSetError;
483
484 fn serialize_element<T>(&mut self, _value: &T) -> Result<(), Self::Error>
485 where
486 T: ?Sized + ser::Serialize,
487 {
488 Ok(())
489 }
490
491 fn end(self) -> Result<Self::Ok, Self::Error> {
492 Ok(None)
493 }
494}
495
496impl ser::SerializeTuple for NoOpSubSerializer {
497 type Ok = Option<ArgType>;
498 type Error = ArgsSetError;
499
500 fn serialize_element<T>(&mut self, _value: &T) -> Result<(), Self::Error>
501 where
502 T: ?Sized + ser::Serialize,
503 {
504 Ok(())
505 }
506
507 fn end(self) -> Result<Self::Ok, Self::Error> {
508 Ok(None)
509 }
510}
511
512impl ser::SerializeTupleStruct for NoOpSubSerializer {
513 type Ok = Option<ArgType>;
514 type Error = ArgsSetError;
515
516 fn serialize_field<T>(&mut self, _value: &T) -> Result<(), Self::Error>
517 where
518 T: ?Sized + ser::Serialize,
519 {
520 Ok(())
521 }
522
523 fn end(self) -> Result<Self::Ok, Self::Error> {
524 Ok(None)
525 }
526}
527
528impl ser::SerializeTupleVariant for NoOpSubSerializer {
529 type Ok = Option<ArgType>;
530 type Error = ArgsSetError;
531
532 fn serialize_field<T>(&mut self, _value: &T) -> Result<(), Self::Error>
533 where
534 T: ?Sized + ser::Serialize,
535 {
536 Ok(())
537 }
538
539 fn end(self) -> Result<Self::Ok, Self::Error> {
540 Ok(None)
541 }
542}
543
544impl ser::SerializeMap for NoOpSubSerializer {
545 type Ok = Option<ArgType>;
546 type Error = ArgsSetError;
547
548 fn serialize_key<T>(&mut self, _key: &T) -> Result<(), Self::Error>
549 where
550 T: ?Sized + ser::Serialize,
551 {
552 Ok(())
553 }
554
555 fn serialize_value<T>(&mut self, _value: &T) -> Result<(), Self::Error>
556 where
557 T: ?Sized + ser::Serialize,
558 {
559 Ok(())
560 }
561
562 fn end(self) -> Result<Self::Ok, Self::Error> {
563 Ok(None)
564 }
565}
566
567impl ser::SerializeStruct for NoOpSubSerializer {
568 type Ok = Option<ArgType>;
569 type Error = ArgsSetError;
570
571 fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<(), Self::Error>
572 where
573 T: ?Sized + ser::Serialize,
574 {
575 Ok(())
576 }
577
578 fn end(self) -> Result<Self::Ok, Self::Error> {
579 Ok(None)
580 }
581}
582
583impl ser::SerializeStructVariant for NoOpSubSerializer {
584 type Ok = Option<ArgType>;
585 type Error = ArgsSetError;
586
587 fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<(), Self::Error>
588 where
589 T: ?Sized + ser::Serialize,
590 {
591 Ok(())
592 }
593
594 fn end(self) -> Result<Self::Ok, Self::Error> {
595 Ok(None)
596 }
597}