From 6520442092ef0bfae09da1bc6acf76e09f269a5c Mon Sep 17 00:00:00 2001 From: bitzoic Date: Fri, 1 Sep 2023 12:54:40 +0200 Subject: [PATCH 01/10] Add SRC-7 files --- standards/Forc.toml | 2 +- standards/src_7/Forc.toml | 5 +++++ standards/src_7/src/src_7.sw | 42 ++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 standards/src_7/Forc.toml create mode 100644 standards/src_7/src/src_7.sw diff --git a/standards/Forc.toml b/standards/Forc.toml index 0ca2b5e..fced462 100644 --- a/standards/Forc.toml +++ b/standards/Forc.toml @@ -1,2 +1,2 @@ [workspace] -members = ["src_3", "src_5", "src_20"] +members = ["src_3", "src_5", "src_7", "src_20"] diff --git a/standards/src_7/Forc.toml b/standards/src_7/Forc.toml new file mode 100644 index 0000000..07e2a98 --- /dev/null +++ b/standards/src_7/Forc.toml @@ -0,0 +1,5 @@ +[project] +authors = ["Fuel Labs "] +entry = "src_7.sw" +license = "Apache-2.0" +name = "src_7" diff --git a/standards/src_7/src/src_7.sw b/standards/src_7/src/src_7.sw new file mode 100644 index 0000000..7ca28ee --- /dev/null +++ b/standards/src_7/src/src_7.sw @@ -0,0 +1,42 @@ +library; + +use std::{bytes::Bytes, string::String}; + +abi SRC7 { + /// Returns metadata for the corresponding `asset` and `key`. + /// + /// # Arguments + /// + /// * `asset`: [AssetId] - The asset of which to query the metadata. + /// * `key`: [String] - The key to the specific metadata. + /// + /// # Returns + /// + /// * [Option] - `Some` metadata that corresponds to the `key` or `None`. + /// + /// # Examples + /// + /// ```sway + /// use src_7::{SRC7, MetadataType}; + /// use std::string::String; + /// + /// fn foo(contract: ContractId, asset: AssetId) { + /// let contract_abi = abi(SRC7, contract); + /// let key = String::from_ascii_str("image"); + /// let data = contract_abi.metadata(asset, key); + /// assert(data.is_some()); + /// } + /// ``` + #[storage(read)] + fn metadata(asset: AssetId, key: String) -> Option; +} + +/// Universal return type for metadata. +pub enum MetadataType { + /// Used when the stored metadata is a `String`. + String: String, + /// Used when the stored metadata is a `u64`. + Int: u64, + /// Used when the stored metadata is a `u64`. + Bytes: Bytes +} From d8af0ceaa31818a23097d57817fab795e4a0cbc8 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Fri, 1 Sep 2023 12:55:57 +0200 Subject: [PATCH 02/10] Add README --- README.md | 1 + .../src_7/.docs/src-7-logo-dark-theme.png | Bin 0 -> 23487 bytes .../src_7/.docs/src-7-logo-light-theme.png | Bin 0 -> 27006 bytes standards/src_7/README.md | 69 ++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 standards/src_7/.docs/src-7-logo-dark-theme.png create mode 100644 standards/src_7/.docs/src-7-logo-light-theme.png create mode 100644 standards/src_7/README.md diff --git a/README.md b/README.md index 00b619c..9fb0efe 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ If you don't find what you're looking for, feel free to create an issue and prop - [SRC-2; Inline Documentation](./standards/src_2/) defines how to document your Sway files. - [SRC-3; Mint and Burn](./standards/src_3/) is used to enabling mint and burn functionality for Native Assets. - [SRC-5; Ownership Standard](./standards/src_5/) is used to restrict function calls to admin users in contracts. +- [SRC-7; Arbitrart Asset Metadata Standard] is used to store metadata for [Native Assets](https://fuellabs.github.io/sway/v0.44.0/book/blockchain-development/native_assets.html). ## Using a standard diff --git a/standards/src_7/.docs/src-7-logo-dark-theme.png b/standards/src_7/.docs/src-7-logo-dark-theme.png new file mode 100644 index 0000000000000000000000000000000000000000..b70e95ca3603783e0d49c4276e87191fc366cd88 GIT binary patch literal 23487 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 + + + SRC-7 logo + +

+ +# Abstract + +The following standard attempts to define the retrieval of on-chain arbitrary metadata for any [Native Asset](https://fuellabs.github.io/sway/v0.45.0/book/blockchain-development/native_assets.html). Any contract that implements the SRC-7 standard MUST implement the [SRC-20](https://github.com/FuelLabs/sway-standards/tree/master/standards/src_20) standard. + +# Motivation + +The SRC-7 standard seeks to enable data-rich assets on the Fuel Network while maintaining compatibility between multiple assets minted by the same contract. The standard ensures type safety with the use of an `enum` and an `Option`. All metadata queries are done through a single function to facilitate cross-contract calls. + +# Prior Art + +The use of generic metadata was originally found in the Sway-Lib's [NFT Library](https://github.com/FuelLabs/sway-libs/tree/v0.12.0/libs/nft) which did not use Fuel's [Native Assets](https://fuellabs.github.io/sway/v0.45.0/book/blockchain-development/native_assets.html). This library has since been deprecated. + +A previous definition for a metadata standard was written in the original edit of the now defunct [SRC-721](https://github.com/FuelLabs/sway-standards/issues/2). This has since been replaced with the [SRC-20](https://github.com/FuelLabs/sway-standards/tree/master/standards/src_20) standard as `SubId` was introduced to enable multiple assets to be minted from a single contract. + +The standard takes inspiration from [ENS's public resolver](https://docs.ens.domains/contract-api-reference/publicresolver) with the use of a `String` as the key. This should enable human-readable keys to help minimize errors and enable the standardization of certain keys, such as "image" as opposed to an `enum` or `u64` representation of keys. + +We also take a look at existing common metadata practices such as [OpenSea's Metadata Standards](https://docs.opensea.io/docs/metadata-standards) and seek to stay backwards compatible with them while enabling more functionality. Through the combination of `String` keys and various return types, both pre-defined URIs or specific attributes may be stored and retrieved with the SRC-7 standard. + +# Specification + +## Metadata Type + +The following describes an enum that wraps various metadata types into a single return type. There SHALL be the following variants in the `MetadataType` enum: + +### - `String: String` + +The **String** variant SHALL be used when the stored metadata for the corresponding asset and key is of the `String` type. The **String** variant MUST be used when a URI is required but MAY contain any arbitrary `String`. + +### - `Int: u64` + +The **Int** variant SHALL be used when the stored metadata for the corresponding asset and key is of the `u64` type. + +### - `Bytes: Bytes` + +The **Bytes** variant SHALL be used when the stored metadata for the corresponding asset and key is of the `Bytes` type. The **Bytes** variant should be used when storing custom data such as but not limited to structs and enums. + +## Require Functions + +### `fn metadata(asset: AssetId, key: String) -> Option` + +This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `String`, `Int`, or `Bytes` variant. If no metadata exists, the function MUST return `None`. + +# Rationale + +The SRC-7 standard should allow for data-rich assets to interact with one another in a safe manner. + +# Backwards Compatibility + +This standard is compatible with Fuel's [Native Assets](https://fuellabs.github.io/sway/v0.45.0/book/blockchain-development/native_assets.html) and the [SRC-20](https://github.com/FuelLabs/sway-standards/tree/master/standards/src_20) standard. It also maintains compatibility with existing standards in other ecosystems. + +# Security Considerations + +This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state. + +# Example ABI + +```rust +abi SRC7Metadata { + #[storage(read)] + fn metadata(asset: AssetId, key: String) -> Option; +} +``` \ No newline at end of file From f1eb130ba2eb09dc10a69b97e07d75a3f8e90b3d Mon Sep 17 00:00:00 2001 From: bitzoic Date: Fri, 1 Sep 2023 12:59:53 +0200 Subject: [PATCH 03/10] Run formatter --- standards/src_7/src/src_7.sw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/standards/src_7/src/src_7.sw b/standards/src_7/src/src_7.sw index 7ca28ee..040e583 100644 --- a/standards/src_7/src/src_7.sw +++ b/standards/src_7/src/src_7.sw @@ -9,7 +9,7 @@ abi SRC7 { /// /// * `asset`: [AssetId] - The asset of which to query the metadata. /// * `key`: [String] - The key to the specific metadata. - /// + /// /// # Returns /// /// * [Option] - `Some` metadata that corresponds to the `key` or `None`. @@ -38,5 +38,5 @@ pub enum MetadataType { /// Used when the stored metadata is a `u64`. Int: u64, /// Used when the stored metadata is a `u64`. - Bytes: Bytes + Bytes: Bytes, } From 8f7ab8a6388b4d3e2de9c152bdb2382d60eae70f Mon Sep 17 00:00:00 2001 From: bitzoic Date: Thu, 7 Sep 2023 10:42:20 +0200 Subject: [PATCH 04/10] Updates to address PR comments --- standards/src_7/README.md | 14 +++++++------- standards/src_7/src/src_7.sw | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/standards/src_7/README.md b/standards/src_7/README.md index 2a92af4..c154fec 100644 --- a/standards/src_7/README.md +++ b/standards/src_7/README.md @@ -29,23 +29,23 @@ We also take a look at existing common metadata practices such as [OpenSea's Met The following describes an enum that wraps various metadata types into a single return type. There SHALL be the following variants in the `MetadataType` enum: -### - `String: String` +### - `StringData: String` -The **String** variant SHALL be used when the stored metadata for the corresponding asset and key is of the `String` type. The **String** variant MUST be used when a URI is required but MAY contain any arbitrary `String`. +The `StringData` variant SHALL be used when the stored metadata for the corresponding asset and key is of the `String` type. The `StringData` variant MUST be used when a URI is required but MAY contain any arbitrary `String`. -### - `Int: u64` +### - `IntData: u64` -The **Int** variant SHALL be used when the stored metadata for the corresponding asset and key is of the `u64` type. +The `IntData` variant SHALL be used when the stored metadata for the corresponding asset and key is of the `u64` type. -### - `Bytes: Bytes` +### - `BytesData: Bytes` -The **Bytes** variant SHALL be used when the stored metadata for the corresponding asset and key is of the `Bytes` type. The **Bytes** variant should be used when storing custom data such as but not limited to structs and enums. +The `BytesData` variant SHALL be used when the stored metadata for the corresponding asset and key is of the `Bytes` type. The `BytesData` variant should be used when storing custom data such as but not limited to structs and enums. ## Require Functions ### `fn metadata(asset: AssetId, key: String) -> Option` -This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `String`, `Int`, or `Bytes` variant. If no metadata exists, the function MUST return `None`. +This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `StringData`, `IntData`, or `BytesData` variant. If no metadata exists, the function MUST return `None`. # Rationale diff --git a/standards/src_7/src/src_7.sw b/standards/src_7/src/src_7.sw index 040e583..ab19222 100644 --- a/standards/src_7/src/src_7.sw +++ b/standards/src_7/src/src_7.sw @@ -20,8 +20,8 @@ abi SRC7 { /// use src_7::{SRC7, MetadataType}; /// use std::string::String; /// - /// fn foo(contract: ContractId, asset: AssetId) { - /// let contract_abi = abi(SRC7, contract); + /// fn foo(contract_id: ContractId, asset: AssetId) { + /// let contract_abi = abi(SRC7, contract_id); /// let key = String::from_ascii_str("image"); /// let data = contract_abi.metadata(asset, key); /// assert(data.is_some()); @@ -34,9 +34,9 @@ abi SRC7 { /// Universal return type for metadata. pub enum MetadataType { /// Used when the stored metadata is a `String`. - String: String, + StringData: String, /// Used when the stored metadata is a `u64`. - Int: u64, + IntData: u64, /// Used when the stored metadata is a `u64`. - Bytes: Bytes, + BytesData: Bytes, } From 0fd44be6d0a770b64a3bbdcbfd9cb49255f5b0f4 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Fri, 8 Sep 2023 11:19:48 +0200 Subject: [PATCH 05/10] Add clarification on asset and key pair --- standards/src_7/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/standards/src_7/README.md b/standards/src_7/README.md index c154fec..ff7018b 100644 --- a/standards/src_7/README.md +++ b/standards/src_7/README.md @@ -31,15 +31,15 @@ The following describes an enum that wraps various metadata types into a single ### - `StringData: String` -The `StringData` variant SHALL be used when the stored metadata for the corresponding asset and key is of the `String` type. The `StringData` variant MUST be used when a URI is required but MAY contain any arbitrary `String`. +The `StringData` variant SHALL be used when the stored metadata for the corresponding asset and `String` key pair is of the `String` type. The `StringData` variant MUST be used when a URI is required but MAY contain any arbitrary `String`. ### - `IntData: u64` -The `IntData` variant SHALL be used when the stored metadata for the corresponding asset and key is of the `u64` type. +The `IntData` variant SHALL be used when the stored metadata for the corresponding asset and `Sting` key pair is of the `u64` type. ### - `BytesData: Bytes` -The `BytesData` variant SHALL be used when the stored metadata for the corresponding asset and key is of the `Bytes` type. The `BytesData` variant should be used when storing custom data such as but not limited to structs and enums. +The `BytesData` variant SHALL be used when the stored metadata for the corresponding asset and `String` key pair is of the `Bytes` type. The `BytesData` variant should be used when storing custom data such as but not limited to structs and enums. ## Require Functions From 3bf3536879107292b1f73678d1864c5a1f0fc5e9 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Fri, 8 Sep 2023 11:21:02 +0200 Subject: [PATCH 06/10] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9fb0efe..5ecec6a 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ If you don't find what you're looking for, feel free to create an issue and prop - [SRC-2; Inline Documentation](./standards/src_2/) defines how to document your Sway files. - [SRC-3; Mint and Burn](./standards/src_3/) is used to enabling mint and burn functionality for Native Assets. - [SRC-5; Ownership Standard](./standards/src_5/) is used to restrict function calls to admin users in contracts. -- [SRC-7; Arbitrart Asset Metadata Standard] is used to store metadata for [Native Assets](https://fuellabs.github.io/sway/v0.44.0/book/blockchain-development/native_assets.html). +- [SRC-7; Arbitrary Asset Metadata Standard] is used to store metadata for [Native Assets](https://fuellabs.github.io/sway/v0.44.0/book/blockchain-development/native_assets.html). ## Using a standard From ce231a825caaaf82b8a86bafd8d452743ac8fb32 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Mon, 11 Sep 2023 12:26:32 +0200 Subject: [PATCH 07/10] Add comment on if no asset exists --- standards/src_7/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standards/src_7/README.md b/standards/src_7/README.md index ff7018b..ad0ecc2 100644 --- a/standards/src_7/README.md +++ b/standards/src_7/README.md @@ -45,7 +45,7 @@ The `BytesData` variant SHALL be used when the stored metadata for the correspon ### `fn metadata(asset: AssetId, key: String) -> Option` -This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `StringData`, `IntData`, or `BytesData` variant. If no metadata exists, the function MUST return `None`. +This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `StringData`, `IntData`, or `BytesData` variant. If the asset does not exist or no metadata exists, the function MUST return `None`. # Rationale From 2655a580a8960b88c70030f3e67add9e64606114 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 12 Sep 2023 12:54:47 +0200 Subject: [PATCH 08/10] Change MetadataType -> Metadata --- standards/src_7/README.md | 6 +++--- standards/src_7/src/src_7.sw | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/standards/src_7/README.md b/standards/src_7/README.md index ad0ecc2..e862227 100644 --- a/standards/src_7/README.md +++ b/standards/src_7/README.md @@ -27,7 +27,7 @@ We also take a look at existing common metadata practices such as [OpenSea's Met ## Metadata Type -The following describes an enum that wraps various metadata types into a single return type. There SHALL be the following variants in the `MetadataType` enum: +The following describes an enum that wraps various metadata types into a single return type. There SHALL be the following variants in the `Metadata` enum: ### - `StringData: String` @@ -43,7 +43,7 @@ The `BytesData` variant SHALL be used when the stored metadata for the correspon ## Require Functions -### `fn metadata(asset: AssetId, key: String) -> Option` +### `fn metadata(asset: AssetId, key: String) -> Option` This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `StringData`, `IntData`, or `BytesData` variant. If the asset does not exist or no metadata exists, the function MUST return `None`. @@ -64,6 +64,6 @@ This standard does not introduce any security concerns, as it does not call exte ```rust abi SRC7Metadata { #[storage(read)] - fn metadata(asset: AssetId, key: String) -> Option; + fn metadata(asset: AssetId, key: String) -> Option; } ``` \ No newline at end of file diff --git a/standards/src_7/src/src_7.sw b/standards/src_7/src/src_7.sw index ab19222..0ee56b5 100644 --- a/standards/src_7/src/src_7.sw +++ b/standards/src_7/src/src_7.sw @@ -12,12 +12,12 @@ abi SRC7 { /// /// # Returns /// - /// * [Option] - `Some` metadata that corresponds to the `key` or `None`. + /// * [Option] - `Some` metadata that corresponds to the `key` or `None`. /// /// # Examples /// /// ```sway - /// use src_7::{SRC7, MetadataType}; + /// use src_7::{SRC7, Metadata}; /// use std::string::String; /// /// fn foo(contract_id: ContractId, asset: AssetId) { @@ -28,15 +28,15 @@ abi SRC7 { /// } /// ``` #[storage(read)] - fn metadata(asset: AssetId, key: String) -> Option; + fn metadata(asset: AssetId, key: String) -> Option; } /// Universal return type for metadata. -pub enum MetadataType { +pub enum Metadata { /// Used when the stored metadata is a `String`. StringData: String, /// Used when the stored metadata is a `u64`. IntData: u64, - /// Used when the stored metadata is a `u64`. + /// Used when the stored metadata is `Bytes`. BytesData: Bytes, } From 97213244de9f737453f98da41f1087d518ae1801 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 12 Sep 2023 12:55:11 +0200 Subject: [PATCH 09/10] Implement Eq for Metadata --- standards/src_7/src/src_7.sw | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/standards/src_7/src/src_7.sw b/standards/src_7/src/src_7.sw index 0ee56b5..f5b7218 100644 --- a/standards/src_7/src/src_7.sw +++ b/standards/src_7/src/src_7.sw @@ -40,3 +40,20 @@ pub enum Metadata { /// Used when the stored metadata is `Bytes`. BytesData: Bytes, } + +impl core::ops::Eq for Metadata { + fn eq(self, other: Self) -> bool { + match (self, other) { + (Metadata::StringData(string1), Metadata::StringData(string2)) => { + string1 == string2 + }, + (Metadata::IntData(int1), Metadata::IntData(int2)) => { + int1 == int2 + }, + (Metadata::BytesData(bytes1), Metadata::BytesData(bytes2)) => { + bytes1 == bytes2 + }, + _ => false, + } + } +} From 820db2837f5a38d5a68785413aa00119f644f6b5 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Thu, 14 Sep 2023 10:20:58 +0200 Subject: [PATCH 10/10] Add b256 to the Metadata enum and rename varients --- standards/src_7/README.md | 18 +++++++++++------- standards/src_7/src/src_7.sw | 25 +++++++++++++++---------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/standards/src_7/README.md b/standards/src_7/README.md index e862227..0e74141 100644 --- a/standards/src_7/README.md +++ b/standards/src_7/README.md @@ -29,23 +29,27 @@ We also take a look at existing common metadata practices such as [OpenSea's Met The following describes an enum that wraps various metadata types into a single return type. There SHALL be the following variants in the `Metadata` enum: -### - `StringData: String` +### - `B256` -The `StringData` variant SHALL be used when the stored metadata for the corresponding asset and `String` key pair is of the `String` type. The `StringData` variant MUST be used when a URI is required but MAY contain any arbitrary `String`. +The `B256` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `Sting` key pair is of the `b256` type. -### - `IntData: u64` +### - `Bytes` -The `IntData` variant SHALL be used when the stored metadata for the corresponding asset and `Sting` key pair is of the `u64` type. +The `Bytes` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `String` key pair is of the `Bytes` type. The `Bytes` variant should be used when storing custom data such as but not limited to structs and enums. -### - `BytesData: Bytes` +### - `Int` -The `BytesData` variant SHALL be used when the stored metadata for the corresponding asset and `String` key pair is of the `Bytes` type. The `BytesData` variant should be used when storing custom data such as but not limited to structs and enums. +The `Int` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `Sting` key pair is of the `u64` type. + +### - `String` + +The `String` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `String` key pair is of the `String` type. The `String` variant MUST be used when a URI is required but MAY contain any arbitrary `String` data. ## Require Functions ### `fn metadata(asset: AssetId, key: String) -> Option` -This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `StringData`, `IntData`, or `BytesData` variant. If the asset does not exist or no metadata exists, the function MUST return `None`. +This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `B256`, `Bytes`, `Int`, or `String` variant. If the asset does not exist or no metadata exists, the function MUST return `None`. # Rationale diff --git a/standards/src_7/src/src_7.sw b/standards/src_7/src/src_7.sw index f5b7218..bb4a473 100644 --- a/standards/src_7/src/src_7.sw +++ b/standards/src_7/src/src_7.sw @@ -33,25 +33,30 @@ abi SRC7 { /// Universal return type for metadata. pub enum Metadata { - /// Used when the stored metadata is a `String`. - StringData: String, - /// Used when the stored metadata is a `u64`. - IntData: u64, + // Used when the stored metadata is a `b256`. + B256: b256, /// Used when the stored metadata is `Bytes`. - BytesData: Bytes, + Bytes: Bytes, + /// Used when the stored metadata is a `u64`. + Int: u64, + /// Used when the stored metadata is a `String`. + String: String, } impl core::ops::Eq for Metadata { fn eq(self, other: Self) -> bool { match (self, other) { - (Metadata::StringData(string1), Metadata::StringData(string2)) => { - string1 == string2 + (Metadata::B256(bytes1), Metadata::B256(bytes2)) => { + bytes1 == bytes2 + }, + (Metadata::Bytes(bytes1), Metadata::Bytes(bytes2)) => { + bytes1 == bytes2 }, - (Metadata::IntData(int1), Metadata::IntData(int2)) => { + (Metadata::Int(int1), Metadata::Int(int2)) => { int1 == int2 }, - (Metadata::BytesData(bytes1), Metadata::BytesData(bytes2)) => { - bytes1 == bytes2 + (Metadata::String(string1), Metadata::String(string2)) => { + string1 == string2 }, _ => false, }