Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better Debug output #11

Open
rlidwka opened this issue Jun 30, 2022 · 3 comments
Open

Better Debug output #11

rlidwka opened this issue Jun 30, 2022 · 3 comments
Milestone

Comments

@rlidwka
Copy link

rlidwka commented Jun 30, 2022

Example:

let mut set = erased_set::ErasedSet::new();
set.insert("foo");
set.insert(42);
dbg!(&set);

Produces this:

[src/bin.rs:309] &set = ErasedSet(
    {
        TypeId {
            t: 3735189839305137790,
        }: Any { .. },
        TypeId {
            t: 13307641874416792075,
        }: Any { .. },
    },
)

I'd like output to be more like this:

[src/bin.rs:309] &set = ErasedSet(
    {
        i32: 42,
        &str: "foo",
    },
)

Formatting of keys

This is pretty straightforward, instead of HashMap<TypeId, T> you can use either HashMap<(TypeId, &str), T> or HashMap<TypeId, (T, &str)> where &str is type_name::<T>().

One possible implementation is in this blog post:
https://lucumr.pocoo.org/2022/1/7/as-any-hack/

Downsides:

It requires extra pointer in data structure. It also requires type names (static strings) to exist somewhere. I'm not sure Rust compiler can optimize them away if &str is stored but never used.

Formatting of values

You can format any values T where T: Debug by having every set member to be dyn DebugAny ; trait DebugAny: Debug + Any instead of dyn Any.

In case T doesn't implement Debug, custom implementation like Any { .. } can be provided.

The problem is: we can't currently check if T implements Debug and run fallback code if it doesn't.

  1. require all T to be Debug
    • maybe separate ErasedSetDebug structure, but number of combinations with Send/Sync variants will be sad
    • or use generic dyn U instead of dyn Any as an argument of hashmap, and offload that problem to user
  2. ask Rust team very nicely to implement specialization
  3. try to find other ways around specialization, such as adding different functions or wrapper types (also quite sad)

Conclusions

Possible - yes. Worth it - don't know.

Am I worrying about debug info too much?

@malobre
Copy link
Owner

malobre commented Jul 2, 2022

Better Debug formatting would be nice.
For the keys, I have implemented a prototype in e1289aa (disabled in release mode).
As for the values, I'm inclined to wait for #7, which would make something like this work out of the box:

impl_erased_set! {
    #[derive(Debug)]
    pub struct MyDebugErasedSet: Any + Debug;
}

@malobre malobre changed the title Better Debug output Better Debug output Jul 2, 2022
@malobre

This comment was marked as outdated.

@malobre
Copy link
Owner

malobre commented Jul 4, 2022

I've made some additional changes, here's the current state of things on main:

  • You can now get an iterator over the type ids currently stored with ErasedSet::type_ids().
  • Unless debug_assertions is disabled (e.g: in release mode), you can retrieve the names of the stored types with ErasedSet::debug_type_names().

@malobre malobre added this to the 1.0.0 milestone Feb 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants