1use std::{
4 any, fmt,
5 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
6 num::{
7 NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize, NonZeroU8,
8 NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
9 },
10 path::PathBuf,
11 str::FromStr,
12};
13
14use serde::{
15 Serialize,
16 de::{DeserializeOwned, Error as DeError},
17};
18
19use crate::{
20 de::{DeserializeContext, deserializer::ValueDeserializer},
21 error::ErrorWithOrigin,
22 metadata::{BasicTypes, ParamMetadata, TypeDescription},
23 value::{Value, WithOrigin},
24};
25
26pub trait DeserializeParam<T>: fmt::Debug + Send + Sync + 'static {
46 const EXPECTING: BasicTypes;
48
49 #[allow(unused)]
51 fn describe(&self, description: &mut TypeDescription) {
52 }
54
55 fn deserialize_param(
61 &self,
62 ctx: DeserializeContext<'_>,
63 param: &'static ParamMetadata,
64 ) -> Result<T, ErrorWithOrigin>;
65
66 fn serialize_param(&self, param: &T) -> serde_json::Value;
71}
72
73#[diagnostic::on_unimplemented(
107 message = "`{Self}` param cannot be deserialized",
108 note = "Add #[config(with = _)] attribute to specify deserializer to use",
109 note = "If `{Self}` is a config, add #[config(nest)] or #[config(flatten)]"
110)]
111pub trait WellKnown: 'static + Sized {
112 type Deserializer: DeserializeParam<Self>;
114 const DE: Self::Deserializer;
116}
117
118#[diagnostic::on_unimplemented(
127 message = "Optional `{Self}` param cannot be deserialized",
128 note = "Add #[config(with = _)] attribute to specify deserializer to use",
129 note = "If `{Self}` is a config, add #[config(nest)]",
130 note = "Embedded options (`Option<Option<_>>`) are not supported as param types"
131)]
132pub trait WellKnownOption: WellKnown {}
133
134pub trait CustomKnownOption: 'static + Send + Sized {
188 type OptDeserializer: DeserializeParam<Option<Self>>;
190 const OPT_DE: Self::OptDeserializer;
192}
193
194impl<T: WellKnownOption + Send> CustomKnownOption for T {
195 type OptDeserializer = Optional<T::Deserializer>;
196 const OPT_DE: Self::OptDeserializer = Optional(Self::DE);
197}
198
199impl<T: WellKnown> DeserializeParam<T> for () {
200 const EXPECTING: BasicTypes = <T::Deserializer as DeserializeParam<T>>::EXPECTING;
201
202 fn describe(&self, description: &mut TypeDescription) {
203 T::DE.describe(description);
204 }
205
206 fn deserialize_param(
207 &self,
208 ctx: DeserializeContext<'_>,
209 param: &'static ParamMetadata,
210 ) -> Result<T, ErrorWithOrigin> {
211 T::DE.deserialize_param(ctx, param)
212 }
213
214 fn serialize_param(&self, param: &T) -> serde_json::Value {
215 T::DE.serialize_param(param)
216 }
217}
218
219pub struct Serde<const EXPECTING: u8>;
222
223impl<const EXPECTING: u8> fmt::Debug for Serde<EXPECTING> {
224 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
225 formatter
226 .debug_tuple("Serde")
227 .field(&BasicTypes::from_raw(EXPECTING))
228 .finish()
229 }
230}
231
232impl<T: Serialize + DeserializeOwned, const EXPECTING: u8> DeserializeParam<T>
233 for Serde<EXPECTING>
234{
235 const EXPECTING: BasicTypes = BasicTypes::from_raw(EXPECTING);
236
237 fn describe(&self, _description: &mut TypeDescription) {
238 }
240
241 fn deserialize_param(
242 &self,
243 ctx: DeserializeContext<'_>,
244 param: &'static ParamMetadata,
245 ) -> Result<T, ErrorWithOrigin> {
246 fn is_likely_large_integer(value: &Value) -> bool {
247 let Value::Number(num) = value else {
248 return false;
249 };
250 if !num.is_f64() {
251 return false;
253 }
254
255 #[allow(clippy::cast_precision_loss)] num.as_f64().is_some_and(|num| {
257 num > u64::MAX as f64 || num < i64::MIN as f64
260 })
261 }
262
263 let expecting = BasicTypes::from_raw(EXPECTING);
264 let Some(current_value) = ctx.current_value() else {
265 return Err(DeError::missing_field(param.name));
266 };
267
268 let deserializer = ValueDeserializer::new(current_value, ctx.de_options);
269 let type_matches = deserializer.value().is_supported_by(expecting);
270 if !type_matches {
271 let tip = if expecting.contains(BasicTypes::INTEGER)
272 && expecting.contains(BasicTypes::STRING)
273 && is_likely_large_integer(deserializer.value())
274 {
275 ". Try enclosing the value into a string so that it's not coerced to floating-point"
277 } else {
278 ""
279 };
280
281 return Err(deserializer.invalid_type(&format!("{expecting}{tip}")));
282 }
283 T::deserialize(deserializer)
284 }
285
286 fn serialize_param(&self, param: &T) -> serde_json::Value {
287 serde_json::to_value(param).expect("failed serializing to JSON")
288 }
289}
290
291impl WellKnown for bool {
292 type Deserializer = super::Serde![bool];
293 const DE: Self::Deserializer = super::Serde![bool];
294}
295
296impl WellKnownOption for bool {}
297
298impl WellKnown for String {
299 type Deserializer = super::Serde![str];
300 const DE: Self::Deserializer = super::Serde![str];
301}
302
303impl WellKnownOption for String {}
304
305impl WellKnown for PathBuf {
306 type Deserializer = Qualified<super::Serde![str]>;
307 const DE: Self::Deserializer = Qualified::new(super::Serde![str], "filesystem path");
308}
309
310impl WellKnownOption for PathBuf {}
311
312impl WellKnown for IpAddr {
313 type Deserializer = Qualified<super::Serde![str]>;
314 const DE: Self::Deserializer = Qualified::new(super::Serde![str], "IP address");
315}
316
317impl WellKnownOption for IpAddr {}
318
319impl WellKnown for Ipv4Addr {
320 type Deserializer = Qualified<super::Serde![str]>;
321 const DE: Self::Deserializer = Qualified::new(super::Serde![str], "IPv4 address");
322}
323
324impl WellKnownOption for Ipv4Addr {}
325
326impl WellKnown for Ipv6Addr {
327 type Deserializer = Qualified<super::Serde![str]>;
328 const DE: Self::Deserializer = Qualified::new(super::Serde![str], "IPv6 address");
329}
330
331impl WellKnownOption for Ipv6Addr {}
332
333impl WellKnown for SocketAddr {
334 type Deserializer = Qualified<super::Serde![str]>;
335 const DE: Self::Deserializer = Qualified::new(super::Serde![str], "socket address");
336}
337
338impl WellKnownOption for SocketAddr {}
339
340impl WellKnown for SocketAddrV4 {
341 type Deserializer = Qualified<super::Serde![str]>;
342 const DE: Self::Deserializer = Qualified::new(super::Serde![str], "v4 socket address");
343}
344
345impl WellKnownOption for SocketAddrV4 {}
346
347impl WellKnown for SocketAddrV6 {
348 type Deserializer = Qualified<super::Serde![str]>;
349 const DE: Self::Deserializer = Qualified::new(super::Serde![str], "v6 socket address");
350}
351
352impl WellKnownOption for SocketAddrV6 {}
353
354impl WellKnown for f32 {
355 type Deserializer = super::Serde![float];
356 const DE: Self::Deserializer = super::Serde![float];
357}
358
359impl WellKnownOption for f32 {}
360
361impl WellKnown for f64 {
362 type Deserializer = super::Serde![float];
363 const DE: Self::Deserializer = super::Serde![float];
364}
365
366impl WellKnownOption for f64 {}
367
368macro_rules! impl_well_known_int {
369 ($($int:ty),+) => {
370 $(
371 impl WellKnown for $int {
372 type Deserializer = super::Serde![int];
373 const DE: Self::Deserializer = super::Serde![int];
374 }
375
376 impl WellKnownOption for $int {}
377 )+
378 };
379}
380
381impl_well_known_int!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);
382
383impl WellKnown for u128 {
386 type Deserializer = super::Serde![int, str];
387 const DE: Self::Deserializer = super::Serde![int, str];
388}
389
390impl WellKnownOption for u128 {}
391
392impl WellKnown for i128 {
395 type Deserializer = super::Serde![int, str];
396 const DE: Self::Deserializer = super::Serde![int, str];
397}
398
399impl WellKnownOption for i128 {}
400
401macro_rules! impl_well_known_non_zero_int {
402 ($($int:ty),+) => {
403 $(
404 impl WellKnown for $int {
405 type Deserializer = Qualified<super::Serde![int]>;
406 const DE: Self::Deserializer = Qualified::new(super::Serde![int], "non-zero");
407 }
408
409 impl WellKnownOption for $int {}
410 )+
411 };
412}
413
414impl_well_known_non_zero_int!(
415 NonZeroU8,
416 NonZeroI8,
417 NonZeroU16,
418 NonZeroI16,
419 NonZeroU32,
420 NonZeroI32,
421 NonZeroU64,
422 NonZeroI64,
423 NonZeroUsize,
424 NonZeroIsize
425);
426
427impl WellKnown for NonZeroU128 {
430 type Deserializer = Qualified<super::Serde![int, str]>;
431 const DE: Self::Deserializer = Qualified::new(super::Serde![int, str], "non-zero");
432}
433
434impl WellKnownOption for NonZeroU128 {}
435
436impl WellKnown for NonZeroI128 {
439 type Deserializer = Qualified<super::Serde![int, str]>;
440 const DE: Self::Deserializer = Qualified::new(super::Serde![int, str], "non-zero");
441}
442
443impl WellKnownOption for NonZeroI128 {}
444
445impl<T: CustomKnownOption> WellKnown for Option<T> {
446 type Deserializer = T::OptDeserializer;
447 const DE: Self::Deserializer = T::OPT_DE;
448}
449
450#[derive(Debug)]
453pub struct Qualified<De> {
454 inner: De,
455 description: &'static str,
457}
458
459impl<De> Qualified<De> {
460 pub const fn new(inner: De, description: &'static str) -> Self {
462 Self { inner, description }
463 }
464}
465
466impl<T, De> DeserializeParam<T> for Qualified<De>
467where
468 De: DeserializeParam<T>,
469{
470 const EXPECTING: BasicTypes = <De as DeserializeParam<T>>::EXPECTING;
471
472 fn describe(&self, description: &mut TypeDescription) {
473 description.set_details(self.description);
474 }
475
476 fn deserialize_param(
477 &self,
478 ctx: DeserializeContext<'_>,
479 param: &'static ParamMetadata,
480 ) -> Result<T, ErrorWithOrigin> {
481 self.inner.deserialize_param(ctx, param)
482 }
483
484 fn serialize_param(&self, param: &T) -> serde_json::Value {
485 self.inner.serialize_param(param)
486 }
487}
488
489pub struct WithDefault<T, D> {
491 inner: D,
492 default: fn() -> T,
493}
494
495impl<T: 'static, D: fmt::Debug> fmt::Debug for WithDefault<T, D> {
496 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
497 formatter
498 .debug_struct("WithDefault")
499 .field("inner", &self.inner)
500 .field("type", &any::type_name::<T>())
501 .finish_non_exhaustive()
502 }
503}
504
505impl<T: 'static, De: DeserializeParam<T>> WithDefault<T, De> {
506 pub const fn new(inner: De, default: fn() -> T) -> Self {
508 Self { inner, default }
509 }
510}
511
512impl<T: 'static, De: DeserializeParam<T>> DeserializeParam<T> for WithDefault<T, De> {
513 const EXPECTING: BasicTypes = De::EXPECTING;
514
515 fn describe(&self, description: &mut TypeDescription) {
516 self.inner.describe(description);
517 }
518
519 fn deserialize_param(
520 &self,
521 ctx: DeserializeContext<'_>,
522 param: &'static ParamMetadata,
523 ) -> Result<T, ErrorWithOrigin> {
524 if ctx.current_value().is_some() {
525 self.inner.deserialize_param(ctx, param)
526 } else {
527 Ok((self.default)())
528 }
529 }
530
531 fn serialize_param(&self, param: &T) -> serde_json::Value {
532 self.inner.serialize_param(param)
533 }
534}
535
536#[derive(Debug)]
559pub struct Optional<De, const AND_THEN: bool = false>(pub De);
560
561impl<De> Optional<De> {
562 pub const fn map(deserializer: De) -> Self {
564 Self(deserializer)
565 }
566}
567
568impl<De> Optional<De, true> {
569 pub const fn and_then(deserializer: De) -> Self {
571 Self(deserializer)
572 }
573}
574
575fn detect_null(ctx: &DeserializeContext<'_>) -> bool {
576 let current_value = ctx.current_value().map(|val| &val.inner);
577 matches!(current_value, None | Some(Value::Null))
578}
579
580impl<T, De: DeserializeParam<T>> DeserializeParam<Option<T>> for Optional<De> {
581 const EXPECTING: BasicTypes = De::EXPECTING;
582
583 fn describe(&self, description: &mut TypeDescription) {
584 self.0.describe(description);
585 }
586
587 fn deserialize_param(
588 &self,
589 ctx: DeserializeContext<'_>,
590 param: &'static ParamMetadata,
591 ) -> Result<Option<T>, ErrorWithOrigin> {
592 if detect_null(&ctx) {
593 return Ok(None);
594 }
595 self.0.deserialize_param(ctx, param).map(Some)
596 }
597
598 fn serialize_param(&self, param: &Option<T>) -> serde_json::Value {
599 if let Some(param) = param {
600 self.0.serialize_param(param)
601 } else {
602 serde_json::Value::Null
603 }
604 }
605}
606
607impl<T, De> DeserializeParam<Option<T>> for Optional<De, true>
608where
609 De: DeserializeParam<Option<T>>,
610{
611 const EXPECTING: BasicTypes = De::EXPECTING;
612
613 fn describe(&self, description: &mut TypeDescription) {
614 self.0.describe(description);
615 }
616
617 fn deserialize_param(
618 &self,
619 ctx: DeserializeContext<'_>,
620 param: &'static ParamMetadata,
621 ) -> Result<Option<T>, ErrorWithOrigin> {
622 if detect_null(&ctx) {
623 return Ok(None);
624 }
625 self.0.deserialize_param(ctx, param)
626 }
627
628 fn serialize_param(&self, param: &Option<T>) -> serde_json::Value {
629 if param.is_some() {
630 self.0.serialize_param(param)
631 } else {
632 serde_json::Value::Null
634 }
635 }
636}
637
638#[derive(Debug)]
681pub struct OrString<De>(pub De);
682
683impl<T, De> DeserializeParam<T> for OrString<De>
684where
685 T: FromStr,
686 T::Err: fmt::Display,
687 De: DeserializeParam<T>,
688{
689 const EXPECTING: BasicTypes = <De as DeserializeParam<T>>::EXPECTING.or(BasicTypes::STRING);
690
691 fn describe(&self, description: &mut TypeDescription) {
692 self.0.describe(description);
693 }
694
695 fn deserialize_param(
696 &self,
697 ctx: DeserializeContext<'_>,
698 param: &'static ParamMetadata,
699 ) -> Result<T, ErrorWithOrigin> {
700 let Some(WithOrigin {
701 inner: Value::String(s),
702 origin,
703 }) = ctx.current_value()
704 else {
705 return self.0.deserialize_param(ctx, param);
706 };
707
708 T::from_str(s.expose()).map_err(|err| {
709 let err = serde_json::Error::custom(err);
710 ErrorWithOrigin::json(err, origin.clone())
711 })
712 }
713
714 fn serialize_param(&self, param: &T) -> serde_json::Value {
715 self.0.serialize_param(param)
716 }
717}