ruffle/core/src/either.rs

22 lines
339 B
Rust
Raw Normal View History

use std::ops::Deref;
avm2: Include class name in ScriptObject debug (#7512) * avm2: Include class name in ScriptObject debug Currently, the `ScriptObject` debug impl is almost useless - while you determine if two printed objects are the same by comparing the pointer value, you'll have no idea what kind of object it actually is. This PR now formats the `ScriptObject` output as a struct, printing a (fake) "class" field containing the class name. Before/after: ``` [ERROR ruffle_core::avm2::activation] AVM2 error: Cannot coerce Object(ScriptObject(ScriptObject(GcCell(Gc { ptr: 0x55f863936db8 })))) to an QName { ns: Private("Test.as$38"), name: "Second" } [ERROR ruffle_core::avm2::activation] AVM2 error: Cannot coerce Object(ScriptObject(ScriptObject { class: "Object", ptr: 0x55ee0ad161e0 })) to an QName { ns: Private("Test.as$38"), name: "Second" } ``` Getting access to the class name from a `Debug` impl is tricky: Developers can (and should be able to) insert logging statements whereever they want, so any `GcCell` may be mutably borrowed. Panics in debug impls are extremely frustrating to deal with, so I've ensured that we only use `try_borrow` at each step. If any of the attempted borrows fail, we print out an error message in the "class_name" field, but we're still able to print the rest of the `ScriptObject`. Additionally, we have no access to a `MutationContext`, so we cannot allocate a new `AvmString`. To get around this, I've created a new method `QName::to_qualified_name_no_mc`, which uses an `Either` to return a `WString` instead of allocating an `AvmString`. This is more cumbersome to work with than the nrmal `QName::to_qualified_name`, so we'll only want to use it when we have no other choice.
2022-08-05 05:13:00 +00:00
pub enum Either<A, B> {
Left(A),
Right(B),
}
impl<A, B> Deref for Either<A, B>
where
A: Deref,
B: Deref<Target = A::Target>,
{
type Target = A::Target;
fn deref(&self) -> &Self::Target {
match self {
Self::Left(a) => a,
Self::Right(b) => b,
}
}
}