all_is_cubes_base/util/
custom_format.rs

1#![allow(clippy::missing_inline_in_public_items)]
2
3use core::fmt;
4use core::marker::PhantomData;
5use core::time::Duration;
6
7use manyfmt::{Fmt, Refmt as _};
8
9/// Format type for [`manyfmt::Fmt`] which prints the name of a type.
10/// The value is a `PhantomData` to avoid requiring an actual instance of the type.
11#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
12#[doc(hidden)] // too specific to be good public API ... arguably should be part of refmt itself.
13#[expect(clippy::exhaustive_structs)]
14pub struct TypeName;
15impl<T> Fmt<TypeName> for PhantomData<T> {
16    fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &TypeName) -> fmt::Result {
17        write!(fmt, "{}", core::any::type_name::<T>())
18    }
19}
20
21/// Format type for [`manyfmt::Fmt`] which is similar to [`fmt::Debug`], but uses an
22/// alternate concise format.
23///
24/// This format may be on one line despite the pretty-printing option, and may lose
25/// precision or Rust syntax in favor of a short at-a-glance representation.
26#[expect(clippy::exhaustive_structs)]
27#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
28pub struct ConciseDebug;
29
30impl<T: Fmt<ConciseDebug>, const N: usize> Fmt<ConciseDebug> for [T; N] {
31    fn fmt(&self, fmt: &mut fmt::Formatter<'_>, fopt: &ConciseDebug) -> fmt::Result {
32        fmt.debug_list()
33            .entries(self.iter().map(|item| item.refmt(fopt)))
34            .finish()
35    }
36}
37
38impl<T: fmt::Debug, U> Fmt<ConciseDebug> for euclid::Point2D<T, U> {
39    fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result {
40        write!(fmt, "({:+.3?}, {:+.3?})", self.x, self.y)
41    }
42}
43impl<T: fmt::Debug, U> Fmt<ConciseDebug> for euclid::Point3D<T, U> {
44    fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result {
45        write!(fmt, "({:+.3?}, {:+.3?}, {:+.3?})", self.x, self.y, self.z)
46    }
47}
48impl<T: fmt::Debug, U> Fmt<ConciseDebug> for euclid::Vector2D<T, U> {
49    fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result {
50        write!(fmt, "({:+.3?}, {:+.3?})", self.x, self.y)
51    }
52}
53impl<T: fmt::Debug, U> Fmt<ConciseDebug> for euclid::Vector3D<T, U> {
54    fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result {
55        write!(fmt, "({:+.3?}, {:+.3?}, {:+.3?})", self.x, self.y, self.z)
56    }
57}
58impl<T: fmt::Debug, U> Fmt<ConciseDebug> for euclid::Size2D<T, U> {
59    fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result {
60        write!(fmt, "({:+.3?}, {:+.3?})", self.width, self.height)
61    }
62}
63impl<T: fmt::Debug, U> Fmt<ConciseDebug> for euclid::Size3D<T, U> {
64    fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result {
65        write!(
66            fmt,
67            "({:+.3?}, {:+.3?}, {:+.3?})",
68            self.width, self.height, self.depth
69        )
70    }
71}
72
73/// Makes the assumption that [`Duration`]s are per-frame timings and hence the
74/// interesting precision is in the millisecond-to-microsecond range.
75impl Fmt<ConciseDebug> for Duration {
76    fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result {
77        write!(fmt, "{:5.2?} ms", (self.as_micros() as f32) / 1000.0)
78    }
79}