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

Restrict Direct Construction of JsValue to Ensure Invariants #3761

Open
HalidOdat opened this issue Mar 24, 2024 · 4 comments
Open

Restrict Direct Construction of JsValue to Ensure Invariants #3761

HalidOdat opened this issue Mar 24, 2024 · 4 comments
Assignees
Labels
good first issue Good for newcomers Internal Category for changelog

Comments

@HalidOdat
Copy link
Member

The problem lies in the ability for users to manually construct a JsValue::Rational from a f64 value that fits within an i32, as JsValue is a public enum.

A proposed solution is to introduce a struct that encapsulates the JsValue enum. By doing so, construction of JsValue::Rational would be limited to its respective constructor functions.

This would allow us to remove many checks that are done to see if a JsValue::Rational f64 value can fit in a i32.

Additional Information

Related to #1373 , something similar was done in #1830 here

@HalidOdat HalidOdat added good first issue Good for newcomers Internal Category for changelog labels Mar 24, 2024
@MartiPresa
Copy link

Is this issue still available?

@jedel1043
Copy link
Member

@MartiPresa Sure! Let me assign it to you.

@jedel1043
Copy link
Member

jedel1043 commented Apr 8, 2024

As a small guidance, the enum you need to work on is here:

pub enum JsValue {
/// `null` - A null value, for when a value doesn't exist.
Null,
/// `undefined` - An undefined value, for when a field or index doesn't exist.
Undefined,
/// `boolean` - A `true` / `false` value, for if a certain criteria is met.
Boolean(bool),
/// `String` - A UTF-16 string, such as `"Hello, world"`.
String(JsString),
/// `Number` - A 64-bit floating point number, such as `3.1415`
Rational(f64),
/// `Number` - A 32-bit integer, such as `42`.
Integer(i32),
/// `BigInt` - holds any arbitrary large signed integer.
BigInt(JsBigInt),
/// `Object` - An object, such as `Math`, represented by a binary tree of string keys to Javascript values.
Object(JsObject),
/// `Symbol` - A Symbol Primitive type.
Symbol(JsSymbol),
}

Ideally, the new repr of JsValue would be:

#[derive(Trace, Finalize, Debug, Clone)]
struct JsValue {
    inner: ValueRepr
}

#[derive(Finalize, Debug, Clone)]
enum ValueRepr {
    Null,
    Undefined,
    /* ... rest of the variants ... */
}

Then, JsValue would need to expose a method to get an enum of the inner variant:

impl JsValue {
    pub variant(&self) -> JsValueVariant<'_> {
        /// Convert from &ValueRepr to JsValueVariant<'_>
    }
}

The rest is fixing all the compilation errors related to the new API, like replacing direct matches of JsValue variables to calls to variant() which match on JsValueVariant.

@MartiPresa
Copy link

MartiPresa commented Apr 9, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers Internal Category for changelog
Projects
None yet
Development

No branches or pull requests

3 participants