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