Repository: LadybirdBrowser/ladybird
File: Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp (C++)

Code before:
Ed448Params::~Ed448Params() = default;

JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> Ed448Params::from_value(JS::VM& vm, JS::Value value)
{
    auto& object = value.as_object();

    auto maybe_context = Optional<ByteBuffer> {};
    if (MUST(object.has_property("context"_utf16_fly_string))) {
        auto context_value = TRY(object.get("context"_utf16_fly_string));
        if (!context_value.is_object() || !(is<JS::TypedArrayBase>(context_value.as_object()) || is<JS::ArrayBuffer>(context_value.as_object()) || is<JS::DataView>(context_value.as_object())))
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
        maybe_context = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(context_value.as_object()));
    }

    return adopt_own<AlgorithmParams>(*new Ed448Params { maybe_context });
}

inline JS::ThrowCompletionOr<Optional<ByteBuffer>>
get_optional_buffer_source(
    JS::VM& vm,
    JS::Object const& object,
    JS::PropertyKey const& name)
{
    auto maybe_buffer = Optional<ByteBuffer> {};

    if (MUST(object.has_property(name))) {
        auto value = TRY(object.get(name));

        if (!value.is_object()
            || !(is<JS::TypedArrayBase>(value.as_object())
                || is<JS::ArrayBuffer>(value.as_object())
                || is<JS::DataView>(value.as_object()))) {
            return vm.throw_completion<JS::TypeError>(
                JS::ErrorType::NotAnObjectOfType,
                "BufferSource");
        }

        maybe_buffer = TRY_OR_THROW_OOM(
            vm,
            WebIDL::get_buffer_source_copy(value.as_object()));
    }

    return maybe_buffer;
}

Argon2Params::~Argon2Params() = default;

JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> Argon2Params::from_value(JS::VM& vm, JS::Value value)
{
    VERIFY(value.is_object());
    auto& object = value.as_object();

Review comment (refactor):
Not sure why this is a `MUST` instead of a `TRY`, and can we move this to an early return? I.e.

```cpp
if (!MUST(object.has_property(name))
    return {}
```

That allows you to get rid of the `auto maybe_buffer = Optional<ByteBuffer> {};`.

Code after:
Ed448Params::~Ed448Params() = default;

JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> Ed448Params::from_value(JS::VM& vm, JS::Value value)
{
    auto& object = value.as_object();

    auto maybe_context = Optional<ByteBuffer> {};
    if (MUST(object.has_property("context"_utf16_fly_string))) {
        auto context_value = TRY(object.get("context"_utf16_fly_string));
        if (!context_value.is_object() || !(is<JS::TypedArrayBase>(context_value.as_object()) || is<JS::ArrayBuffer>(context_value.as_object()) || is<JS::DataView>(context_value.as_object())))
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
        maybe_context = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(context_value.as_object()));
    }

    return adopt_own<AlgorithmParams>(*new Ed448Params { maybe_context });
}

static inline JS::ThrowCompletionOr<Optional<ByteBuffer>> get_optional_buffer_source(JS::VM& vm, JS::Object const& object, JS::PropertyKey const& name)
{
    if (!TRY(object.has_property(name)))
        return OptionalNone {};

    auto value = TRY(object.get(name));

    if (!WebIDL::is_buffer_source_type(value))
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");

    return TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(value.as_object()));
}

Argon2Params::~Argon2Params() = default;

JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> Argon2Params::from_value(JS::VM& vm, JS::Value value)
{
    VERIFY(value.is_object());
    auto& object = value.as_object();

    if (!MUST(object.has_property("nonce"_utf16_fly_string))) {
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::MissingRequiredProperty, "nonce");
    }
    auto nonce_value = TRY(object.get("nonce"_utf16_fly_string));
    if (!nonce_value.is_object() || !(is<JS::TypedArrayBase>(nonce_value.as_object()) || is<JS::ArrayBuffer>(nonce_value.as_object()) || is<JS::DataView>(nonce_value.as_object())))
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
    auto const nonce = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(nonce_value.as_object()));

    auto const extract_u32_value = [&](auto const& name) -> JS::ThrowCompletionOr<WebIDL::UnsignedLong> {
        if (!MUST(object.has_property(name))) {
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::MissingRequiredProperty, name);
        }
        auto key_value = TRY(object.get(name));
        return WebIDL::convert_to_int<WebIDL::UnsignedLong>(vm, key_value, WebIDL::EnforceRange::Yes, WebIDL::Clamp::No);