diff --git a/CHANGELOG.md b/CHANGELOG.md index 099ca5931..8604c927d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,10 @@ This avoids confusion between points in space and cube-identifying coordinates. - Renamed `raytracer::PixelBuf` trait to `Accumulate`. + - `all_is_cubes::util::CustomFormat` has been split into a separate library called `manyfmt`, + reexported at `all_is_cubes::util::manyfmt`. + The `CustomFormat` trait is now split into two traits, `Fmt` (for implementing) and `Refmt` (extension). + - `all-is-cubes-mesh` library: - Renamed `TextureAllocator` to `texture::Allocator`. - Renamed `TextureTile` to `texture::Tile`. diff --git a/Cargo.lock b/Cargo.lock index 73a301c05..587746676 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,6 +70,7 @@ dependencies = [ "indoc", "itertools 0.11.0", "log", + "manyfmt", "mutants", "num-traits", "once_cell", @@ -2224,6 +2225,12 @@ dependencies = [ "libc", ] +[[package]] +name = "manyfmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc8a8ffbc9351ccb4e059baa1b271b643444237d841f4624a379735249d174d6" + [[package]] name = "matchit" version = "0.7.1" diff --git a/Cargo.toml b/Cargo.toml index 5a9c8e9f8..8256800d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ instant = "0.1.12" itertools = { version = "0.11.0", default-features = false, features = ["use_alloc"] } log = { version = "0.4.17", default-features = false } macro_rules_attribute = "0.2.0" +manyfmt = "0.1.0" mutants = "0.0.3" num-traits = { version = "0.2.15", default-features = false } once_cell = "1.17.1" diff --git a/all-is-cubes-desktop/src/terminal/ui.rs b/all-is-cubes-desktop/src/terminal/ui.rs index 7c3d2db07..ca53e56a6 100644 --- a/all-is-cubes-desktop/src/terminal/ui.rs +++ b/all-is-cubes-desktop/src/terminal/ui.rs @@ -19,7 +19,7 @@ use all_is_cubes::character::{Character, Cursor}; use all_is_cubes::euclid::Vector2D; use all_is_cubes::inv::Slot; use all_is_cubes::universe::URef; -use all_is_cubes::util::{CustomFormat, StatusText}; +use all_is_cubes::util::{Refmt as _, StatusText}; use crate::terminal::chars::{image_patch_to_character, write_colored_and_measure}; use crate::terminal::TextRayImage; @@ -478,7 +478,7 @@ impl TerminalState { ); f.render_widget( - Paragraph::new(format!("{}", info.custom_format(StatusText))), + Paragraph::new(format!("{}", info.refmt(&StatusText))), render_info_rect, ); } diff --git a/all-is-cubes-gpu/src/common/info.rs b/all-is-cubes-gpu/src/common/info.rs index ca9ee9879..bfec50906 100644 --- a/all-is-cubes-gpu/src/common/info.rs +++ b/all-is-cubes-gpu/src/common/info.rs @@ -2,7 +2,7 @@ use std::fmt; use std::time::Duration; use all_is_cubes::camera::{Flaws, Layers}; -use all_is_cubes::util::{CustomFormat, StatusText}; +use all_is_cubes::util::{Fmt, Refmt, StatusText}; use all_is_cubes_mesh::dynamic::CsmUpdateInfo; /// Performance info about drawing an entire scene. @@ -61,8 +61,8 @@ pub struct DrawInfo { pub(crate) submit_time: Option, } -impl CustomFormat for RenderInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: StatusText) -> fmt::Result { +impl Fmt for RenderInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &StatusText) -> fmt::Result { let &Self { waiting_for_gpu, update: @@ -93,14 +93,14 @@ impl CustomFormat for RenderInfo { fmt, // TODO: adjust this format to account for more pieces "Frame time: {} (GPU wait {}, update {}, draw world {}, ui {}", - total_time.custom_format(StatusText), - waiting_for_gpu.custom_format(StatusText), - update_time.custom_format(StatusText), - draw_time.world.custom_format(StatusText), - draw_time.ui.custom_format(StatusText), + total_time.refmt(&StatusText), + waiting_for_gpu.refmt(&StatusText), + update_time.refmt(&StatusText), + draw_time.world.refmt(&StatusText), + draw_time.ui.refmt(&StatusText), )?; if let Some(t) = submit_time { - write!(fmt, ", submit {}", t.custom_format(StatusText))?; + write!(fmt, ", submit {}", t.refmt(&StatusText))?; } writeln!(fmt, ")")?; @@ -108,27 +108,27 @@ impl CustomFormat for RenderInfo { write!( fmt, "Update breakdown: prep {}, world mesh {}, ui mesh {}, lines {}", - update_prep_time.custom_format(StatusText), - update_spaces.world.total_time.custom_format(StatusText), - update_spaces.ui.total_time.custom_format(StatusText), - lines_time.custom_format(StatusText), + update_prep_time.refmt(&StatusText), + update_spaces.world.total_time.refmt(&StatusText), + update_spaces.ui.total_time.refmt(&StatusText), + lines_time.refmt(&StatusText), )?; if let Some(t) = update_submit_time { - write!(fmt, ", submit {}", t.custom_format(StatusText))?; + write!(fmt, ", submit {}", t.refmt(&StatusText))?; } // Spaces write!( fmt, "\n\nWORLD:\n{}\n{}\n\n", - update_spaces.world.custom_format(StatusText), - draw_spaces.world.custom_format(StatusText) + update_spaces.world.refmt(&StatusText), + draw_spaces.world.refmt(&StatusText) )?; write!( fmt, "UI:\n{}\n{}", - update_spaces.ui.custom_format(StatusText), - draw_spaces.ui.custom_format(StatusText) + update_spaces.ui.refmt(&StatusText), + draw_spaces.ui.refmt(&StatusText) )?; write!(fmt, "\nRender flaws: {flaws}")?; @@ -164,8 +164,8 @@ impl SpaceUpdateInfo { } } -impl CustomFormat for SpaceUpdateInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, format_type: StatusText) -> fmt::Result { +impl Fmt for SpaceUpdateInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, fopt: &StatusText) -> fmt::Result { let &SpaceUpdateInfo { total_time: _, // we print this as summary info from the parent only ref chunk_info, @@ -174,14 +174,14 @@ impl CustomFormat for SpaceUpdateInfo { light_update_count, } = self; - let light_update_time = light_update_time.custom_format(format_type); + let light_update_time = light_update_time.refmt(fopt); - writeln!(fmt, "{}", chunk_info.custom_format(format_type))?; + writeln!(fmt, "{}", chunk_info.refmt(fopt))?; writeln!( fmt, "Light: {light_update_count:3} cubes in {light_update_time}" )?; - write!(fmt, "{:#?}", texture_info.custom_format(StatusText))?; + write!(fmt, "{:#?}", texture_info.refmt(fopt))?; Ok(()) } } @@ -217,8 +217,8 @@ pub struct SpaceDrawInfo { pub(crate) flaws: Flaws, } -impl CustomFormat for SpaceDrawInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, format_type: StatusText) -> fmt::Result { +impl Fmt for SpaceDrawInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, fopt: &StatusText) -> fmt::Result { let &SpaceDrawInfo { draw_init_time, draw_opaque_time, @@ -228,9 +228,9 @@ impl CustomFormat for SpaceDrawInfo { flaws: _, // TODO: include or exclude? } = self; - let draw_init_time = draw_init_time.custom_format(format_type); - let draw_opaque_time = draw_opaque_time.custom_format(format_type); - let draw_transparent_time = draw_transparent_time.custom_format(format_type); + let draw_init_time = draw_init_time.refmt(fopt); + let draw_opaque_time = draw_opaque_time.refmt(fopt); + let draw_transparent_time = draw_transparent_time.refmt(fopt); writeln!( fmt, @@ -268,8 +268,8 @@ impl Default for BlockTextureInfo { } } -impl CustomFormat for BlockTextureInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, format_type: StatusText) -> fmt::Result { +impl Fmt for BlockTextureInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, fopt: &StatusText) -> fmt::Result { write!( fmt, "Textures: {} tiles, {} texels ({}% of {}) used, {:2} flushed in {}", @@ -278,7 +278,7 @@ impl CustomFormat for BlockTextureInfo { (self.in_use_texels as f32 / self.capacity_texels as f32 * 100.0).ceil() as usize, self.capacity_texels, self.flushed, - self.flush_time.custom_format(format_type) + self.flush_time.refmt(fopt) ) } } diff --git a/all-is-cubes-gpu/tests/shaders/wgsl.rs b/all-is-cubes-gpu/tests/shaders/wgsl.rs index 3af745f5b..be5afa029 100644 --- a/all-is-cubes-gpu/tests/shaders/wgsl.rs +++ b/all-is-cubes-gpu/tests/shaders/wgsl.rs @@ -2,7 +2,7 @@ use std::fmt; -use all_is_cubes::util::CustomFormat; +use all_is_cubes::util::{Fmt, Refmt as _}; /// Generate a fragment shader entry point from an expression. pub fn frag_expr(expr: &str) -> String { @@ -22,30 +22,30 @@ trait WgslTypeName { #[derive(Clone, Copy, Debug)] pub struct ToWgsl; -pub fn to_wgsl>(value: T) -> String { - value.custom_format(ToWgsl).to_string() +pub fn to_wgsl>(value: T) -> String { + value.refmt(&ToWgsl).to_string() } -impl CustomFormat for f32 { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: ToWgsl) -> fmt::Result { +impl Fmt for f32 { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ToWgsl) -> fmt::Result { write!(fmt, "{:?}", self) } } -impl CustomFormat for [T; 4] +impl Fmt for [T; 4] where - T: CustomFormat + WgslTypeName, + T: Fmt + WgslTypeName, { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, f: ToWgsl) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, f: &ToWgsl) -> fmt::Result { let [x, y, z, w] = self; let t = T::wgsl_type_name(); write!( fmt, "vec4<{t}>({x}, {y}, {z}, {w})", - x = x.custom_format(f), - y = y.custom_format(f), - z = z.custom_format(f), - w = w.custom_format(f), + x = x.refmt(f), + y = y.refmt(f), + z = z.refmt(f), + w = w.refmt(f), ) } } diff --git a/all-is-cubes-mesh/src/block_vertex.rs b/all-is-cubes-mesh/src/block_vertex.rs index 840abb70c..b3ebf6387 100644 --- a/all-is-cubes-mesh/src/block_vertex.rs +++ b/all-is-cubes-mesh/src/block_vertex.rs @@ -4,7 +4,7 @@ use std::fmt; use all_is_cubes::euclid::Point3D; use all_is_cubes::math::{Cube, Face6, FreeCoordinate, FreePoint, FreeVector, Rgba}; -use all_is_cubes::util::{ConciseDebug, CustomFormat}; +use all_is_cubes::util::{ConciseDebug, Fmt, Refmt as _}; /// Basic vertex data type for a [`BlockMesh`]. /// Implement [`From`]<[`BlockVertex`]> (and usually [`GfxVertex`]) @@ -77,7 +77,7 @@ where write!( fmt, "{{ p: {:?} n: {:?} c: {:?} }}", - self.position.custom_format(ConciseDebug), + self.position.refmt(&ConciseDebug), self.face, self.coloring ) @@ -85,14 +85,14 @@ where } impl fmt::Debug for Coloring where - T: CustomFormat, // TODO: inelegant + T: Fmt, // TODO: inelegant { // TODO: test formatting of this fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Coloring::Solid(color) => write!(fmt, "Solid({color:?})"), Coloring::Texture { pos, .. } => { - write!(fmt, "Texture({:?})", pos.custom_format(ConciseDebug)) + write!(fmt, "Texture({:?})", pos.refmt(&ConciseDebug)) } } } diff --git a/all-is-cubes-mesh/src/dynamic/blocks.rs b/all-is-cubes-mesh/src/dynamic/blocks.rs index e8960eca0..2d0555022 100644 --- a/all-is-cubes-mesh/src/dynamic/blocks.rs +++ b/all-is-cubes-mesh/src/dynamic/blocks.rs @@ -5,7 +5,7 @@ use fnv::FnvHashSet; use all_is_cubes::block::{EvaluatedBlock, Resolution}; use all_is_cubes::space::{BlockIndex, Space}; use all_is_cubes::time; -use all_is_cubes::util::{CustomFormat as _, StatusText, TimeStats}; +use all_is_cubes::util::{Refmt as _, StatusText, TimeStats}; use crate::texture; use crate::{BlockMesh, GetBlockMesh, GfxVertex, MeshOptions, SpaceMesh}; @@ -196,7 +196,7 @@ where if duration > time::Duration::from_millis(4) { log::trace!( "Block mesh took {}: {:?} {:?}", - duration.custom_format(StatusText), + duration.refmt(&StatusText), new_evaluated_block.attributes.display_name, bd.block(), ); diff --git a/all-is-cubes-mesh/src/dynamic/chunk.rs b/all-is-cubes-mesh/src/dynamic/chunk.rs index 703b5892c..75c36232b 100644 --- a/all-is-cubes-mesh/src/dynamic/chunk.rs +++ b/all-is-cubes-mesh/src/dynamic/chunk.rs @@ -90,13 +90,13 @@ where // if vertices == 0 { // log::trace!( // "meshed {:?}+ in {:.3} ms, 0", - // chunk_origin.custom_format(ConciseDebug), + // chunk_origin.refmt(&ConciseDebug), // duration_ms, // ); // } else { // log::trace!( // "meshed {:?}+ in {:.3} ms, {} in {:.3} µs/v", - // chunk_origin.custom_format(ConciseDebug), + // chunk_origin.refmt(&ConciseDebug), // duration_ms, // vertices, // duration_ms * (1000.0 / vertices as f32), diff --git a/all-is-cubes-mesh/src/dynamic/chunked_mesh.rs b/all-is-cubes-mesh/src/dynamic/chunked_mesh.rs index 57c3033e3..70f92a94d 100644 --- a/all-is-cubes-mesh/src/dynamic/chunked_mesh.rs +++ b/all-is-cubes-mesh/src/dynamic/chunked_mesh.rs @@ -12,7 +12,7 @@ use all_is_cubes::math::{Cube, Face6, FreeCoordinate, GridCoordinate, LineVertex use all_is_cubes::space::{BlockIndex, Space, SpaceChange}; use all_is_cubes::time::{self, Duration}; use all_is_cubes::universe::URef; -use all_is_cubes::util::{CustomFormat, StatusText, TimeStats}; +use all_is_cubes::util::{Fmt, Refmt, StatusText, TimeStats}; use crate::dynamic::{self, ChunkMesh, ChunkTodo}; use crate::texture; @@ -428,7 +428,7 @@ where space = self.space().name(), time = end_all_time .saturating_duration_since(self.zero_time) - .custom_format(StatusText) + .refmt(&StatusText) ); self.complete_time = Some(end_all_time); } @@ -513,8 +513,8 @@ pub struct CsmUpdateInfo { pub chunk_total_cpu_byte_size: usize, } -impl CustomFormat for CsmUpdateInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: StatusText) -> fmt::Result { +impl Fmt for CsmUpdateInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &StatusText) -> fmt::Result { let CsmUpdateInfo { flaws, total_time: _, @@ -539,14 +539,12 @@ impl CustomFormat for CsmUpdateInfo { Mem: {chunk_mib} MiB for {chunk_count} chunks\ "}, flaws = flaws, - prep_time = prep_time.custom_format(StatusText), + prep_time = prep_time.refmt(&StatusText), block_updates = block_updates, - chunk_scan_time = chunk_scan_time.custom_format(StatusText), + chunk_scan_time = chunk_scan_time.refmt(&StatusText), chunk_mesh_generation_times = chunk_mesh_generation_times, chunk_mesh_callback_times = chunk_mesh_callback_times, - depth_sort_time = depth_sort_time - .unwrap_or(Duration::ZERO) - .custom_format(StatusText), + depth_sort_time = depth_sort_time.unwrap_or(Duration::ZERO).refmt(&StatusText), chunk_mib = chunk_total_cpu_byte_size / (1024 * 1024), chunk_count = chunk_count, ) diff --git a/all-is-cubes-mesh/src/texture.rs b/all-is-cubes-mesh/src/texture.rs index b37a833e7..863c90ae9 100644 --- a/all-is-cubes-mesh/src/texture.rs +++ b/all-is-cubes-mesh/src/texture.rs @@ -7,7 +7,7 @@ use all_is_cubes::block::{Evoxel, Evoxels}; use all_is_cubes::content::palette; use all_is_cubes::euclid::Point3D; use all_is_cubes::math::{Cube, GridAab}; -use all_is_cubes::util::{ConciseDebug, CustomFormat}; +use all_is_cubes::util::{ConciseDebug, Fmt}; #[cfg(doc)] use all_is_cubes::math::GridArray; @@ -252,8 +252,8 @@ impl Plane for NoTexture { } } -impl CustomFormat for NoTexture { - fn fmt(&self, _: &mut fmt::Formatter<'_>, _: ConciseDebug) -> fmt::Result { +impl Fmt for NoTexture { + fn fmt(&self, _: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result { match *self {} } } diff --git a/all-is-cubes-port/src/mv.rs b/all-is-cubes-port/src/mv.rs index b7c336997..07407e70b 100644 --- a/all-is-cubes-port/src/mv.rs +++ b/all-is-cubes-port/src/mv.rs @@ -8,7 +8,7 @@ use all_is_cubes::linking::InGenError; use all_is_cubes::math::{Cube, GridAab, GridRotation, GridVector, Gridgid, Rgb, Rgba, VectorOps}; use all_is_cubes::space::{LightPhysics, SetCubeError, Space}; use all_is_cubes::universe::{self, Name, PartialUniverse, Universe}; -use all_is_cubes::util::{ConciseDebug, CustomFormat, YieldProgress}; +use all_is_cubes::util::{ConciseDebug, Refmt, YieldProgress}; use crate::{ExportError, ExportSet}; @@ -211,7 +211,7 @@ fn space_to_dot_vox_model( name: Some(space_ref.name()), reason: format!( "space of size {} is too large to export to .vox; must be 256 or less in each axis", - bounds.size().custom_format(ConciseDebug) + bounds.size().refmt(&ConciseDebug) ), }); } diff --git a/all-is-cubes-ui/src/apps/session.rs b/all-is-cubes-ui/src/apps/session.rs index 7287f0e03..b43a10207 100644 --- a/all-is-cubes-ui/src/apps/session.rs +++ b/all-is-cubes-ui/src/apps/session.rs @@ -18,7 +18,7 @@ use all_is_cubes::listen::{ use all_is_cubes::time::{self, Duration}; use all_is_cubes::transaction::{self, Transaction as _}; use all_is_cubes::universe::{URef, Universe, UniverseStepInfo}; -use all_is_cubes::util::{CustomFormat, StatusText}; +use all_is_cubes::util::{Fmt, Refmt as _, StatusText}; use crate::apps::{FpsCounter, FrameClock, InputProcessor, InputTargets}; use crate::ui_content::Vui; @@ -304,7 +304,7 @@ impl Session { log::debug!( "tick={} step {}", self.tick_counter_for_logging, - info.computation_time.custom_format(StatusText) + info.computation_time.refmt(&StatusText) ); } self.last_step_info = info.clone(); @@ -421,12 +421,12 @@ impl Session { /// Returns textual information intended to be overlaid as a HUD on top of the rendered scene /// containing diagnostic information about rendering and stepping. - pub fn info_text>(&self, render: T) -> InfoText<'_, I, T> { + pub fn info_text>(&self, render: T) -> InfoText<'_, I, T> { if LOG_FIRST_FRAMES && self.tick_counter_for_logging <= 10 { log::debug!( "tick={} draw {}", self.tick_counter_for_logging, - render.custom_format(StatusText) + render.refmt(&StatusText) ) } @@ -596,25 +596,20 @@ pub struct InfoText<'a, I, T> { render: T, } -impl> fmt::Display for InfoText<'_, I, T> { +impl> fmt::Display for InfoText<'_, I, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(character_ref) = self.session.game_character.borrow() { - write!( - f, - "{}", - character_ref.read().unwrap().custom_format(StatusText) - ) - .unwrap(); + write!(f, "{}", character_ref.read().unwrap().refmt(&StatusText)).unwrap(); } write!( f, "\n\n{:#?}\n\nFPS: {:2.1}\n{:#?}\n\n", - self.session.last_step_info.custom_format(StatusText), + self.session.last_step_info.refmt(&StatusText), self.session .frame_clock .draw_fps_counter() .frames_per_second(), - self.render.custom_format(StatusText), + self.render.refmt(&StatusText), )?; match self.session.cursor_result() { Some(cursor) => write!(f, "{cursor}"), diff --git a/all-is-cubes/Cargo.toml b/all-is-cubes/Cargo.toml index 217094907..b9522a9d4 100644 --- a/all-is-cubes/Cargo.toml +++ b/all-is-cubes/Cargo.toml @@ -86,6 +86,7 @@ hashbrown = { workspace = true } indoc = { workspace = true } itertools = { workspace = true } log = { workspace = true } +manyfmt = { workspace = true } mutants = { workspace = true } num-traits = { workspace = true } once_cell = { workspace = true, optional = true } diff --git a/all-is-cubes/src/character.rs b/all-is-cubes/src/character.rs index 766f26606..1f200b1f2 100644 --- a/all-is-cubes/src/character.rs +++ b/all-is-cubes/src/character.rs @@ -5,6 +5,7 @@ use core::fmt; use euclid::{Angle, Point3D, Rotation3D, Vector3D}; use hashbrown::HashSet as HbHashSet; +use manyfmt::Fmt; use ordered_float::NotNan; #[cfg(not(feature = "std"))] @@ -28,7 +29,7 @@ use crate::transaction::{ self, CommitError, Merge, PreconditionFailed, Transaction, Transactional, }; use crate::universe::{RefVisitor, URef, UniverseTransaction, VisitRefs}; -use crate::util::{ConciseDebug, CustomFormat, StatusText}; +use crate::util::{ConciseDebug, Refmt as _, StatusText}; mod cursor; pub use cursor::*; @@ -105,10 +106,7 @@ impl fmt::Debug for Character { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("Character") .field("body", &self.body) - .field( - "velocity_input", - &self.velocity_input.custom_format(ConciseDebug), - ) + .field("velocity_input", &self.velocity_input.refmt(&ConciseDebug)) .field("colliding_cubes", &self.colliding_cubes) // TODO: report light samples .field("exposure", &self.exposure_log.exp()) @@ -118,12 +116,12 @@ impl fmt::Debug for Character { } } -impl CustomFormat for Character { +impl Fmt for Character { #[mutants::skip] // technically user visible but really debugging - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: StatusText) -> fmt::Result { - writeln!(fmt, "{}", self.body.custom_format(StatusText))?; + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &StatusText) -> fmt::Result { + writeln!(fmt, "{}", self.body.refmt(&StatusText))?; if let Some(info) = &self.last_step_info { - writeln!(fmt, "Last step: {:#?}", info.custom_format(ConciseDebug))?; + writeln!(fmt, "Last step: {:#?}", info.refmt(&ConciseDebug))?; } write!(fmt, "Colliding: {:?}", self.colliding_cubes.len()) } diff --git a/all-is-cubes/src/math.rs b/all-is-cubes/src/math.rs index 6926c942c..6d0c8a2b9 100644 --- a/all-is-cubes/src/math.rs +++ b/all-is-cubes/src/math.rs @@ -8,7 +8,7 @@ pub use ordered_float::{FloatIsNan, NotNan}; /// Acts as polyfill for float methods use num_traits::float::FloatCore as _; -use crate::util::{ConciseDebug, CustomFormat}; +use crate::util::ConciseDebug; mod aab; pub use aab::*; diff --git a/all-is-cubes/src/math/cube.rs b/all-is-cubes/src/math/cube.rs index ae2d79780..1a7127f50 100644 --- a/all-is-cubes/src/math/cube.rs +++ b/all-is-cubes/src/math/cube.rs @@ -175,8 +175,8 @@ impl fmt::Debug for Cube { write!(f, "({x:+.3?}, {y:+.3?}, {z:+.3?})") } } -impl crate::util::CustomFormat for Cube { - fn fmt(&self, f: &mut fmt::Formatter<'_>, _: ConciseDebug) -> fmt::Result { +impl manyfmt::Fmt for Cube { + fn fmt(&self, f: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result { fmt::Debug::fmt(self, f) } } diff --git a/all-is-cubes/src/math/face.rs b/all-is-cubes/src/math/face.rs index d1962ea28..278577f54 100644 --- a/all-is-cubes/src/math/face.rs +++ b/all-is-cubes/src/math/face.rs @@ -8,9 +8,10 @@ use euclid::Vector3D; pub use ordered_float::{FloatIsNan, NotNan}; use crate::math::{ - Axis, ConciseDebug, Cube, CustomFormat, FreeCoordinate, Geometry, GridCoordinate, GridPoint, - GridRotation, GridVector, Gridgid, LineVertex, VectorOps, Zero, + Axis, ConciseDebug, Cube, FreeCoordinate, Geometry, GridCoordinate, GridPoint, GridRotation, + GridVector, Gridgid, LineVertex, VectorOps, Zero, }; +use crate::util::Refmt as _; /// Identifies a face of a cube or an orthogonal unit vector. /// @@ -772,7 +773,7 @@ impl fmt::Debug for CubeFace { write!( fmt, "CubeFace({:?}, {:?})", - self.cube.custom_format(ConciseDebug), + self.cube.refmt(&ConciseDebug), self.face, ) } diff --git a/all-is-cubes/src/physics/body.rs b/all-is-cubes/src/physics/body.rs index b908e77c1..d3f6c671f 100644 --- a/all-is-cubes/src/physics/body.rs +++ b/all-is-cubes/src/physics/body.rs @@ -1,6 +1,7 @@ use core::fmt; use euclid::Vector3D; +use manyfmt::Fmt; use ordered_float::NotNan; #[cfg(not(feature = "std"))] @@ -19,7 +20,7 @@ use crate::raycast::Ray; use crate::space::Space; use crate::time::Tick; use crate::transaction::{self, Transaction}; -use crate::util::{ConciseDebug, CustomFormat, StatusText}; +use crate::util::{ConciseDebug, Refmt as _, StatusText}; /// Velocities shorter than this are treated as zero, to allow things to come to unchanging rest sooner. const VELOCITY_EPSILON_SQUARED: FreeCoordinate = 1e-6 * 1e-6; @@ -82,8 +83,8 @@ impl fmt::Debug for Body { pitch, } = self; fmt.debug_struct("Body") - .field("position", &position.custom_format(ConciseDebug)) - .field("velocity", &velocity.custom_format(ConciseDebug)) + .field("position", &position.refmt(&ConciseDebug)) + .field("velocity", &velocity.refmt(&ConciseDebug)) .field("collision_box", &collision_box) .field("flying", &flying) .field("noclip", &noclip) @@ -94,15 +95,15 @@ impl fmt::Debug for Body { } /// Omits collision box on the grounds that it is presumably constant -impl CustomFormat for Body { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: StatusText) -> fmt::Result { +impl Fmt for Body { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &StatusText) -> fmt::Result { write!( fmt, "Position: {} Yaw: {:5.1}° Pitch: {:5.1}°\nVelocity: {}", - self.position.custom_format(ConciseDebug), + self.position.refmt(&ConciseDebug), self.yaw, self.pitch, - self.velocity.custom_format(ConciseDebug), + self.velocity.refmt(&ConciseDebug), )?; if self.flying { write!(fmt, " Flying")?; @@ -441,19 +442,13 @@ pub struct BodyStepInfo { pub move_segments: [MoveSegment; 3], } -impl CustomFormat for BodyStepInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, format_type: ConciseDebug) -> fmt::Result { +impl Fmt for BodyStepInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, fopt: &ConciseDebug) -> fmt::Result { fmt.debug_struct("BodyStepInfo") .field("quiescent", &self.quiescent) .field("already_colliding", &self.already_colliding) - .field( - "push_out", - &self.push_out.as_ref().map(|v| v.custom_format(format_type)), - ) - .field( - "move_segments", - &self.move_segments.custom_format(format_type), - ) + .field("push_out", &self.push_out.as_ref().map(|v| v.refmt(fopt))) + .field("move_segments", &self.move_segments.refmt(fopt)) .finish() } } @@ -470,16 +465,12 @@ pub struct MoveSegment { pub stopped_by: Option, } -impl CustomFormat for MoveSegment { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: ConciseDebug) -> fmt::Result { +impl Fmt for MoveSegment { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, fopt: &ConciseDebug) -> fmt::Result { let mut nonempty = false; if self.delta_position != FreeVector::zero() { nonempty = true; - write!( - fmt, - "move {:?}", - self.delta_position.custom_format(ConciseDebug) - )?; + write!(fmt, "move {:?}", self.delta_position.refmt(fopt))?; } if let Some(stopped_by) = &self.stopped_by { if nonempty { diff --git a/all-is-cubes/src/physics/collision.rs b/all-is-cubes/src/physics/collision.rs index 756684935..68b42549f 100644 --- a/all-is-cubes/src/physics/collision.rs +++ b/all-is-cubes/src/physics/collision.rs @@ -20,7 +20,7 @@ use crate::math::{ }; use crate::raycast::{Ray, Raycaster}; use crate::space::Space; -use crate::util::{ConciseDebug, CustomFormat, MapExtend}; +use crate::util::{ConciseDebug, MapExtend, Refmt as _}; /// An individual collision contact; something in a [`Space`] that a moving [`Aab`] /// collided with. @@ -96,7 +96,7 @@ impl fmt::Debug for Contact { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Block(CubeFace { cube, face }) => { - write!(f, "{face:?} of {}", cube.custom_format(ConciseDebug)) + write!(f, "{face:?} of {}", cube.refmt(&ConciseDebug)) } Self::Voxel { cube, @@ -106,8 +106,8 @@ impl fmt::Debug for Contact { f, "{:?} of {} {}/{}", face, - cube.custom_format(ConciseDebug), - voxel.custom_format(ConciseDebug), + cube.refmt(&ConciseDebug), + voxel.refmt(&ConciseDebug), resolution ), } diff --git a/all-is-cubes/src/raytracer.rs b/all-is-cubes/src/raytracer.rs index 8a3a10054..2183eb741 100644 --- a/all-is-cubes/src/raytracer.rs +++ b/all-is-cubes/src/raytracer.rs @@ -13,11 +13,11 @@ use alloc::vec::Vec; use core::fmt; use euclid::{vec3, Vector2D, Vector3D}; -use ordered_float::NotNan; - +use manyfmt::Fmt; #[cfg(not(feature = "std"))] /// Acts as polyfill for float methods use num_traits::float::Float as _; +use ordered_float::NotNan; #[cfg(feature = "threads")] use rayon::iter::{IntoParallelIterator as _, ParallelIterator as _}; @@ -33,7 +33,7 @@ use crate::math::{ }; use crate::raycast::Ray; use crate::space::{BlockIndex, PackedLight, Space, SpaceBlockData}; -use crate::util::{CustomFormat, StatusText}; +use crate::util::StatusText; mod accum; pub use accum::*; @@ -432,8 +432,8 @@ impl core::iter::Sum for RaytraceInfo { } } -impl CustomFormat for RaytraceInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _format_type: StatusText) -> fmt::Result { +impl Fmt for RaytraceInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &StatusText) -> fmt::Result { let &Self { cubes_traced } = self; write!(fmt, "Cubes traced: {cubes_traced}") } diff --git a/all-is-cubes/src/raytracer/updating.rs b/all-is-cubes/src/raytracer/updating.rs index 2189c43dc..59c862421 100644 --- a/all-is-cubes/src/raytracer/updating.rs +++ b/all-is-cubes/src/raytracer/updating.rs @@ -209,8 +209,8 @@ mod tests { use crate::content::make_some_voxel_blocks; use crate::raytracer::{CharacterBuf, CharacterRtData}; use crate::universe::Universe; - use crate::util::{CustomFormat, Unquote}; use euclid::{vec2, vec3}; + use manyfmt::{formats::Unquote, Refmt}; use pretty_assertions::assert_eq; struct EquivalenceTester { @@ -266,10 +266,7 @@ mod tests { ) .trace_scene_to_string::(&self.camera, "\n"); - assert_eq!( - image_updating.custom_format(Unquote), - image_fresh.custom_format(Unquote) - ); + assert_eq!(image_updating.refmt(&Unquote), image_fresh.refmt(&Unquote)); print!("{image_updating}"); Ok(()) } diff --git a/all-is-cubes/src/space.rs b/all-is-cubes/src/space.rs index 67edae3ba..73da977ed 100644 --- a/all-is-cubes/src/space.rs +++ b/all-is-cubes/src/space.rs @@ -10,6 +10,7 @@ use core::time::Duration; use euclid::{vec3, Vector3D}; use hashbrown::HashSet as HbHashSet; +use manyfmt::Fmt; use crate::behavior::{self, BehaviorSet}; use crate::block::TickAction; @@ -31,7 +32,7 @@ use crate::physics::Acceleration; use crate::time; use crate::transaction::{Merge, Transaction as _}; use crate::universe::{RefVisitor, URef, UniverseTransaction, VisitRefs}; -use crate::util::{ConciseDebug, CustomFormat, StatusText, TimeStats}; +use crate::util::{ConciseDebug, Refmt as _, StatusText, TimeStats}; mod builder; pub use builder::{SpaceBuilder, SpaceBuilderBounds}; @@ -882,7 +883,7 @@ impl fmt::Debug for SpacePhysics { f.debug_struct("SpacePhysics") .field( "gravity", - &gravity.map(NotNan::into_inner).custom_format(ConciseDebug), + &gravity.map(NotNan::into_inner).refmt(&ConciseDebug), ) .field("sky_color", &sky_color) .field("light", &light) @@ -1051,8 +1052,8 @@ impl core::ops::AddAssign for SpaceStepInfo { self.light += other.light; } } -impl CustomFormat for SpaceStepInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: StatusText) -> fmt::Result { +impl Fmt for SpaceStepInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, fopt: &StatusText) -> fmt::Result { let Self { spaces, evaluations, @@ -1062,9 +1063,9 @@ impl CustomFormat for SpaceStepInfo { light, } = self; if self.spaces > 0 { - let light = light.custom_format(StatusText); - let cube_time = cube_time.custom_format(StatusText); - let behaviors_time = behaviors_time.custom_format(StatusText); + let light = light.refmt(fopt); + let cube_time = cube_time.refmt(fopt); + let behaviors_time = behaviors_time.refmt(fopt); write!( fmt, "\ diff --git a/all-is-cubes/src/space/light/updater.rs b/all-is-cubes/src/space/light/updater.rs index e67a479b0..72796f062 100644 --- a/all-is-cubes/src/space/light/updater.rs +++ b/all-is-cubes/src/space/light/updater.rs @@ -7,6 +7,7 @@ use core::cmp::Ordering; use core::fmt; use euclid::{Point3D, Vector3D}; +use manyfmt::Fmt; use super::debug::LightComputeOutput; use super::LightUpdateRequest; @@ -16,7 +17,7 @@ use crate::raycast::{Ray, RaycastStep}; use crate::space::light::{LightUpdateRayInfo, Priority}; use crate::space::{GridAab, LightPhysics, PackedLight, PackedLightScalar, Space, SpaceChange}; use crate::time::{Duration, Instant}; -use crate::util::{CustomFormat, StatusText}; +use crate::util::StatusText; /// This parameter determines to what degree absorption of light due to a block surface's /// color is taken into account. At zero, it is not (all surfaces are perfectly @@ -532,8 +533,8 @@ impl core::ops::AddAssign for LightUpdatesInfo { self.max_queue_priority = self.max_queue_priority.max(other.max_queue_priority); } } -impl CustomFormat for LightUpdatesInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: StatusText) -> fmt::Result { +impl Fmt for LightUpdatesInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &StatusText) -> fmt::Result { write!( fmt, "{:4} (max diff {:3}) of {:4} (max pri {:3?})", diff --git a/all-is-cubes/src/space/space_txn.rs b/all-is-cubes/src/space/space_txn.rs index 550f0429c..91c3331c7 100644 --- a/all-is-cubes/src/space/space_txn.rs +++ b/all-is-cubes/src/space/space_txn.rs @@ -15,7 +15,7 @@ use crate::space::{ActivatableRegion, GridAab, SetCubeError, Space}; use crate::transaction::{ no_outputs, CommitError, Merge, NoOutput, PreconditionFailed, Transaction, Transactional, }; -use crate::util::{ConciseDebug, CustomFormat as _}; +use crate::util::{ConciseDebug, Refmt as _}; impl Transactional for Space { type Transaction = SpaceTransaction; @@ -365,10 +365,7 @@ impl fmt::Debug for SpaceTransaction { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let mut ds = fmt.debug_struct("SpaceTransaction"); for (cube, txn) in &self.cubes { - ds.field( - &Cube::from(*cube).custom_format(ConciseDebug).to_string(), - txn, - ); + ds.field(&Cube::from(*cube).refmt(&ConciseDebug).to_string(), txn); } if !self.behaviors.is_empty() { ds.field("behaviors", &self.behaviors); @@ -403,11 +400,9 @@ impl std::error::Error for SpaceTransactionConflict { impl fmt::Display for SpaceTransactionConflict { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - SpaceTransactionConflict::Cube { cube, conflict: _ } => write!( - f, - "conflict at cube {c}", - c = cube.custom_format(ConciseDebug) - ), + SpaceTransactionConflict::Cube { cube, conflict: _ } => { + write!(f, "conflict at cube {c}", c = cube.refmt(&ConciseDebug)) + } SpaceTransactionConflict::Behaviors(_) => write!(f, "conflict in behaviors"), } } diff --git a/all-is-cubes/src/universe.rs b/all-is-cubes/src/universe.rs index 0df80cad2..96ebeb0e8 100644 --- a/all-is-cubes/src/universe.rs +++ b/all-is-cubes/src/universe.rs @@ -20,12 +20,14 @@ use alloc::vec::Vec; use core::fmt; use core::sync::atomic::{self, Ordering}; +use manyfmt::Fmt; + use crate::block::BlockDef; use crate::character::Character; use crate::space::{Space, SpaceStepInfo}; use crate::time; use crate::transaction::Transaction as _; -use crate::util::{CustomFormat, StatusText}; +use crate::util::{Refmt as _, StatusText}; // Note: Most things in `members` are either an impl, private, or intentionally public-in-private. // Therefore, no glob reexport. @@ -665,8 +667,8 @@ impl core::ops::AddAssign for UniverseStepInfo { self.space_step += other.space_step; } } -impl CustomFormat for UniverseStepInfo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: StatusText) -> fmt::Result { +impl Fmt for UniverseStepInfo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, fopt: &StatusText) -> fmt::Result { let Self { computation_time, active_members, @@ -676,9 +678,9 @@ impl CustomFormat for UniverseStepInfo { writeln!( fmt, "Step computation: {t} for {active_members} of {total_members}", - t = computation_time.custom_format(StatusText), + t = computation_time.refmt(fopt), )?; - write!(fmt, "{}", space_step.custom_format(StatusText))?; + write!(fmt, "{}", space_step.refmt(fopt))?; Ok(()) } } diff --git a/all-is-cubes/src/universe/members.rs b/all-is-cubes/src/universe/members.rs index 73d70deb8..5cba1ada4 100644 --- a/all-is-cubes/src/universe/members.rs +++ b/all-is-cubes/src/universe/members.rs @@ -18,7 +18,7 @@ use crate::universe::{ universe_txn as ut, InsertError, Name, PartialUniverse, URef, URefErased, URootRef, Universe, UniverseIter, }; -use crate::util::CustomFormat as _; +use crate::util::Refmt as _; /// A `BTreeMap` is used to ensure that the iteration order is deterministic across /// runs/versions. @@ -451,7 +451,7 @@ where // }; ds.field( &name.to_string(), - &core::marker::PhantomData::.custom_format(crate::util::TypeName), + &core::marker::PhantomData::.refmt(&crate::util::TypeName), ); } } diff --git a/all-is-cubes/src/util.rs b/all-is-cubes/src/util.rs index a171759b3..d3561da59 100644 --- a/all-is-cubes/src/util.rs +++ b/all-is-cubes/src/util.rs @@ -14,6 +14,9 @@ pub mod maybe_sync; #[doc(no_inline)] pub use yield_progress::{Builder as YieldProgressBuilder, YieldProgress}; +#[doc(no_inline)] +pub use manyfmt::{refmt, Fmt, Refmt}; + #[doc(hidden)] pub fn yield_progress_for_testing() -> YieldProgress { // Theoretically we should use Tokio's yield function, but it shouldn't matter for @@ -34,7 +37,7 @@ mod error_chain { /// /// The text begins with the [`core::fmt::Display`] format of the error. /// - /// Design note: This is not a [`CustomFormat`] because that has a blanket implementation + /// Design note: This is not a [`manyfmt::Fmt`] because that has a blanket implementation /// which interferes with this one for [`Error`]. #[doc(hidden)] // not something we wish to be stable public API #[derive(Clone, Copy, Debug)] @@ -192,17 +195,17 @@ impl fmt::Display for TimeStats { None => write!( f, "(-------- .. {}) for {:3}, total {}", - self.max.custom_format(StatusText), + self.max.refmt(&StatusText), self.count, - self.sum.custom_format(StatusText), + self.sum.refmt(&StatusText), ), Some(min) => write!( f, "({} .. {}) for {:3}, total {}", - min.custom_format(StatusText), - self.max.custom_format(StatusText), + min.refmt(&StatusText), + self.max.refmt(&StatusText), self.count, - self.sum.custom_format(StatusText), + self.sum.refmt(&StatusText), ), } } diff --git a/all-is-cubes/src/util/custom_format.rs b/all-is-cubes/src/util/custom_format.rs index a018107e8..964dc9389 100644 --- a/all-is-cubes/src/util/custom_format.rs +++ b/all-is-cubes/src/util/custom_format.rs @@ -1,77 +1,20 @@ -use alloc::string::String; use core::fmt; use core::marker::PhantomData; use core::time::Duration; -/// Generic extension to [`core::fmt`'s set of formatting traits](core::fmt#formatting-traits). -/// -/// This can be thought of as a mechanism to easily create a new special-purpose -/// formatting trait, analogous to [`fmt::LowerHex`] or [`fmt::Pointer`]. -/// Instead of implementing the entire necessary wrapper and setup code, implementations -/// need only be types representing the choice of formatting (e.g. [`ConciseDebug`]), -/// and [`CustomFormat::custom_format`] provides a wrapper which may be used to cause -/// a value implementing `CustomFormat` to be formatted using -/// [`CustomFormat::fmt`](Self::fmt). -pub trait CustomFormat { - /// Wrap this value so that when formatted with [`fmt::Debug`] or [`fmt::Display`], it uses - /// the given custom format instead. - fn custom_format(&self, format_type: F) -> CustomFormatWrapper<'_, F, Self> { - CustomFormatWrapper(format_type, self) - } - - /// Implement this to provide custom formatting for this type. - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, format_type: F) -> fmt::Result; -} - -/// You can use [`CustomFormat::custom_format`] to construct this. -/// See its documentation. -/// -/// To enable using the wrapper inside [`assert_eq`], it implements [`PartialEq`] -/// (comparing both value and format). -#[derive(Eq, PartialEq)] -pub struct CustomFormatWrapper<'a, F: Copy, T: CustomFormat + ?Sized>(F, &'a T); -impl<'a, F: Copy, T: CustomFormat> fmt::Debug for CustomFormatWrapper<'a, F, T> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - >::fmt(self.1, fmt, self.0) - } -} -impl<'a, F: Copy, T: CustomFormat> fmt::Display for CustomFormatWrapper<'a, F, T> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - >::fmt(self.1, fmt, self.0) - } -} - -impl> CustomFormat for &'_ T { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, format_type: F) -> fmt::Result { - >::fmt(&**self, fmt, format_type) - } -} +use manyfmt::{Fmt, Refmt as _}; -/// Format type for [`CustomFormat`] which forces a string to be unquoted when [`fmt::Debug`]ged. -#[derive(Clone, Copy, Eq, Hash, PartialEq)] -pub(crate) struct Unquote; -impl CustomFormat for String { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: Unquote) -> fmt::Result { - write!(fmt, "{self}") - } -} -impl CustomFormat for &'_ str { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: Unquote) -> fmt::Result { - write!(fmt, "{self}") - } -} - -/// Format type for [`CustomFormat`] which prints the name of a type. +/// Format type for [`manyfmt::Fmt`] which prints the name of a type. /// The value is a `PhantomData` to avoid requiring an actual instance of the type. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub(crate) struct TypeName; -impl CustomFormat for PhantomData { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: TypeName) -> fmt::Result { +impl Fmt for PhantomData { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &TypeName) -> fmt::Result { write!(fmt, "{}", core::any::type_name::()) } } -/// Format type for [`CustomFormat`] which is similar to [`fmt::Debug`], but uses an +/// Format type for [`manyfmt::Fmt`] which is similar to [`fmt::Debug`], but uses an /// alternate concise format. /// /// This format may be on one line despite the pretty-printing option, and may lose @@ -80,36 +23,36 @@ impl CustomFormat for PhantomData { #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct ConciseDebug; -impl, const N: usize> CustomFormat for [T; N] { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, format_type: ConciseDebug) -> fmt::Result { +impl, const N: usize> Fmt for [T; N] { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, fopt: &ConciseDebug) -> fmt::Result { fmt.debug_list() - .entries(self.iter().map(|item| item.custom_format(format_type))) + .entries(self.iter().map(|item| item.refmt(fopt))) .finish() } } -impl CustomFormat for euclid::Point2D { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: ConciseDebug) -> fmt::Result { +impl Fmt for euclid::Point2D { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result { write!(fmt, "({:+.3?}, {:+.3?})", self.x, self.y) } } -impl CustomFormat for euclid::Point3D { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: ConciseDebug) -> fmt::Result { +impl Fmt for euclid::Point3D { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result { write!(fmt, "({:+.3?}, {:+.3?}, {:+.3?})", self.x, self.y, self.z) } } -impl CustomFormat for euclid::Vector2D { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: ConciseDebug) -> fmt::Result { +impl Fmt for euclid::Vector2D { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result { write!(fmt, "({:+.3?}, {:+.3?})", self.x, self.y) } } -impl CustomFormat for euclid::Vector3D { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: ConciseDebug) -> fmt::Result { +impl Fmt for euclid::Vector3D { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &ConciseDebug) -> fmt::Result { write!(fmt, "({:+.3?}, {:+.3?}, {:+.3?})", self.x, self.y, self.z) } } -/// Format type for [`CustomFormat`] which provides an highly condensed, ideally +/// Format type for [`manyfmt::Fmt`] which provides an highly condensed, ideally /// constant-size, user-facing format for live-updating textual status messages. /// This format does not follow Rust [`fmt::Debug`] syntax, and when implemented /// for standard Rust types may have quirks. Values may have multiple lines. @@ -119,26 +62,8 @@ pub struct StatusText; /// Makes the assumption that [`Duration`]s are per-frame timings and hence the /// interesting precision is in the millisecond-to-microsecond range. -impl CustomFormat for Duration { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: StatusText) -> fmt::Result { +impl Fmt for Duration { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: &StatusText) -> fmt::Result { write!(fmt, "{:5.2?} ms", (self.as_micros() as f32) / 1000.0) } } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn basic_concise_debug() { - #[derive(Debug)] - struct Foo; - impl CustomFormat for Foo { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>, _: ConciseDebug) -> fmt::Result { - write!(fmt, "") - } - } - assert_eq!("Foo", format!("{Foo:?}")); - assert_eq!("", format!("{:?}", Foo.custom_format(ConciseDebug))); - } -} diff --git a/fuzz/fuzz_targets/fuzz_physics.rs b/fuzz/fuzz_targets/fuzz_physics.rs index 8da365682..720e6fc88 100644 --- a/fuzz/fuzz_targets/fuzz_physics.rs +++ b/fuzz/fuzz_targets/fuzz_physics.rs @@ -7,7 +7,7 @@ use all_is_cubes::math::{self, Aab, FreeCoordinate, NotNan, VectorOps}; use all_is_cubes::space::Space; use all_is_cubes::time::Tick; use all_is_cubes::universe::Universe; -use all_is_cubes::util::{ConciseDebug, CustomFormat}; +use all_is_cubes::util::{ConciseDebug, Refmt as _}; use libfuzzer_sys::fuzz_target; @@ -25,8 +25,8 @@ fuzz_target!(|input: ([FreeCoordinate; 3], [FreeCoordinate; 3], Space)| { println!( "{} {}", - position.custom_format(ConciseDebug), - velocity.custom_format(ConciseDebug) + position.refmt(&ConciseDebug), + velocity.refmt(&ConciseDebug) ); let mut universe = Universe::new(); diff --git a/test-renderers/src/harness.rs b/test-renderers/src/harness.rs index 1b4b9c11d..b6de7ba6b 100644 --- a/test-renderers/src/harness.rs +++ b/test-renderers/src/harness.rs @@ -14,7 +14,7 @@ use itertools::Itertools; use all_is_cubes::camera::{Flaws, HeadlessRenderer, Rendering}; use all_is_cubes::universe::Universe; -use all_is_cubes::util::{CustomFormat as _, StatusText}; +use all_is_cubes::util::{Refmt as _, StatusText}; use crate::{ results_json_path, write_report_file, ComparisonOutcome, ComparisonRecord, ImageId, Overlays, @@ -302,7 +302,7 @@ where Ok(case_time) => { match format { Format::Pretty => { - println!(" ok in {}", case_time.custom_format(StatusText)) + println!(" ok in {}", case_time.refmt(&StatusText)) } Format::Terse => print!("."), }