| // Copyright (c) 2024, 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 'hooks/syntax.g.dart'; | |
| /// An encoded asset. | |
| /// | |
| /// Use a protocol extension such as `package:code_assets` or | |
| /// `package:data_assets` to encode and decode assets. | |
| final class EncodedAsset { | |
| /// The type of the asset (e.g. whether it's a code asset, data asset or ...) | |
| final String type; | |
| /// The json encoding of the asset. | |
| final UnmodifiableMapView<String, Object?> encoding; | |
| /// The path of the [encoding] in a larger JSON. | |
| /// | |
| /// If provided, used for more precise error messages. | |
| final List<Object>? encodingJsonPath; | |
| /// Creates an [EncodedAsset]. | |
| EncodedAsset( | |
| this.type, | |
| Map<String, Object?> encoding, { | |
| this.encodingJsonPath, | |
| }) : encoding = UnmodifiableMapView( | |
| // It would be better if `encoding` would be deep copied. | |
| // https://github.com/dart-lang/native/issues/2045 | |
| Map.of(encoding), | |
| ); | |
| /// Decode an [EncodedAsset] from json. | |
| factory EncodedAsset.fromJson( | |
| Map<String, Object?> json, [ | |
| List<Object>? path, | |
| ]) => EncodedAssetSyntaxExtension.fromSyntax( | |
| AssetSyntax.fromJson(json, path: path ?? []), | |
| ); | |
| /// Encode this [EncodedAsset] tojson. | |
| Map<String, Object?> toJson() => toSyntax().json; | |
| @override | |
| String toString() => 'EncodedAsset($type, $encoding)'; | |
| @override | |
| int get hashCode => Object.hash(type, const DeepCollectionEquality().hash); | |
| @override | |
| bool operator ==(Object other) => | |
| other is EncodedAsset && | |
| type == other.type && | |
| const DeepCollectionEquality().equals(encoding, other.encoding); | |
| } | |
| /// Extension methods for [EncodedAsset] to convert to and from syntax | |
| /// nodes. | |
| extension EncodedAssetSyntaxExtension on EncodedAsset { | |
| /// Creates a [EncodedAsset] from a [AssetSyntax] node. | |
| static EncodedAsset fromSyntax(AssetSyntax syntaxNode) => EncodedAsset( | |
| syntaxNode.type, | |
| syntaxNode.encoding?.json ?? {}, | |
| encodingJsonPath: syntaxNode.encoding?.path, | |
| ); | |
| /// Converts this [EncodedAsset] to a [AssetSyntax] node. | |
| AssetSyntax toSyntax() { | |
| final path = switch (encodingJsonPath) { | |
| // Remove the last element from the encoding path. | |
| final List<Object> l => l.sublist(0, l.length - 1), | |
| null => <Object>[], | |
| }; | |
| return AssetSyntax( | |
| encoding: JsonObjectSyntax.fromJson(Map.of(encoding)), | |
| type: type, | |
| path: path, | |
| ); | |
| } | |
| } |