Conversation
The Deserialize derive macro writes code only for structs with named fields. Some types are difficult to write with this macro, for example enums and the shape of a JSON metafield. This change adds the `#[shopify_function(serde)]` attribute. The macro then writes an implementation that uses serde. The type keeps its own name. Then the `custom_scalar_overrides` argument of a query can refer to the type. A generic wrapper type cannot do this, because the argument does not accept generic arguments. The new `serde_adapter` module holds a serde deserializer for the input of the Wasm API. The deserializer reads the input values directly. It does not build an intermediate JSON tree. The public `from_value` function keeps the error message from serde. serde was already in the dependency tree, because serde_json needs it. This change makes the dependency direct. The size of the Wasm output does not change. Assisted-By: devx/019ff170-a20d-7ca9-9f19-e3273cbb2420
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this change does
The
Deserializederive macro writes code only for structs with named fields. Some types are difficult to write with this macro, for example enums and the shape of a JSON metafield.This change adds the
#[shopify_function(serde)]attribute to the derive macro. The macro then writes an implementation that dispatches to serde:All serde attributes apply, because serde does the work.
Why the change exists
The primary use is the
custom_scalar_overridesargument of a query. That argument accepts only a path to a type, and it refuses generic arguments. Therefore a generic wrapper type, such asSerdeAdapter<T>, cannot be a target. The attribute puts the implementation on the type itself, and the type keeps its own name:The accessor for that field then gives a
&Configuration.How it works
The new
shopify_function::serde_adaptermodule holds a serde deserializer for the input of the Wasm API:serde_json::Valuetree.deserialize_anyis available. Therefore#[serde(untagged)]types andserde_json::Valuealso work.from_valuefunction keeps the error message from serde. The derive macro maps the error toread::Error::InvalidType, because that type cannot hold a message.The derive macro refuses these combinations, and it shows a clear message for each one:
serdetogether withrename_allserdetogether with ashopify_functionattribute on a field or a variantserdeattributeLimits
All strings from the input are owned. Therefore types that borrow from the input, for example fields with
#[serde(borrow)], do not work.This change gives no support for serialization with serde.
Dependency
serde was already in the dependency tree, because
serde_json,rmp-serdeandexample_with_targetsneed it. This change makes the dependency direct, and it adds no new package. The only change inCargo.lockis one line.Tests
shopify_function/tests/serde_adapter_test.rshas 11 tests: simple enums, an unknown value, a value that is not a string, error messages, nested types, a missing field, a number out of range, enums with fields, untagged enums, a generic type, and a function input.shopify_function/tests/serde_custom_scalar_override_test.rstests the full path throughtypegenandcustom_scalar_overrides, for a required field and for an optional field.Checks
cargo testfor the workspace: all tests pass.cargo fmt --all --checkandcargo clippy --all-targets: no messages.example_with_targetskeeps its size of 35156 bytes.