blob: f7052efe9a300407d03acae57349f9f77aa0e1f6 [file] [log] [blame] [edit]
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:collection/collection.dart';
import 'config.dart';
import 'encoded_asset.dart';
import 'hooks/syntax.g.dart';
/// An asset that contains metadata.
///
/// Should only be used with [ToLinkHook] and [ToBuildHooks].
//
// Note: not exported to public API. The public API only contains a way to read
// and write metadata, it doesn't expose the underlying mechanism.
final class MetadataAsset {
/// The key for the metadata.
final String key;
/// The value of the metadata.
final Object? value;
/// Creates a [MetadataAsset].
MetadataAsset({required this.key, required this.value});
/// Creates a [MetadataAsset] from an [EncodedAsset].
factory MetadataAsset.fromEncoded(EncodedAsset asset) {
assert(asset.type == _type);
final syntaxNode = MetadataAssetEncodingSyntax.fromJson(
asset.encoding,
path: asset.encodingJsonPath ?? [],
);
return MetadataAsset(key: syntaxNode.key, value: syntaxNode.value);
}
@override
bool operator ==(Object other) {
if (other is! MetadataAsset) {
return false;
}
return other.key == key &&
const DeepCollectionEquality().equals(value, other.value);
}
@override
int get hashCode =>
Object.hash(key, const DeepCollectionEquality().hash(value));
/// Encodes this [MetadataAsset] into an [EncodedAsset].
EncodedAsset encode() => EncodedAsset(_type, {'key': key, 'value': value});
@override
String toString() => 'MetadataAsset(${encode().encoding})';
static const _type = 'hooks/metadata';
}
/// Extension methods for [EncodedAsset] to handle metadata.
extension EncodedMetadataAsset on EncodedAsset {
/// Whether this asset is a metadata asset.
bool get isMetadataAsset => type == MetadataAsset._type;
/// Converts this asset to a [MetadataAsset].
///
/// Requires [isMetadataAsset] to be true.
MetadataAsset get asMetadataAsset => MetadataAsset.fromEncoded(this);
}