Skip to main content

arete_hash/
kind.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3use std::str::FromStr;
4
5use crate::HashError;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[serde(rename_all = "kebab-case")]
9pub enum CanonicalizationProfile {
10    RawBytesV1,
11    AreteJcsV1,
12    FramedTupleV1,
13    ArtifactTreeV1,
14}
15
16impl CanonicalizationProfile {
17    pub const fn as_str(self) -> &'static str {
18        match self {
19            Self::RawBytesV1 => "raw-bytes-v1",
20            Self::AreteJcsV1 => "arete-jcs-v1",
21            Self::FramedTupleV1 => "framed-tuple-v1",
22            Self::ArtifactTreeV1 => "artifact-tree-v1",
23        }
24    }
25}
26
27impl fmt::Display for CanonicalizationProfile {
28    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
29        formatter.write_str(self.as_str())
30    }
31}
32
33impl FromStr for CanonicalizationProfile {
34    type Err = HashError;
35
36    fn from_str(value: &str) -> Result<Self, Self::Err> {
37        match value {
38            "raw-bytes-v1" => Ok(Self::RawBytesV1),
39            "arete-jcs-v1" => Ok(Self::AreteJcsV1),
40            "framed-tuple-v1" => Ok(Self::FramedTupleV1),
41            "artifact-tree-v1" => Ok(Self::ArtifactTreeV1),
42            _ => Err(HashError::InvalidHashId("unknown canonicalization profile")),
43        }
44    }
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
48#[serde(rename_all = "kebab-case")]
49pub enum HashKindName {
50    IdlSource,
51    IdlContent,
52    IdlPortable,
53    IdlNormalized,
54    ProgramSpec,
55    AstPortable,
56    RuntimeArtifact,
57    ArtifactFile,
58    DecoderContent,
59    SdkDefinition,
60    SdkExtension,
61    SdkOutputTree,
62    Compiler,
63    ProgramRelease,
64    LiveSpec,
65    StackManifest,
66    DeploymentRelease,
67    DecoderFixtureSet,
68    KnowledgeDocument,
69    KnowledgeSnapshot,
70    ExtensionSurface,
71    SdkInstallTarget,
72    CatalogBundle,
73    CatalogPublicationSet,
74    ProtocolSpec,
75    ProtocolHandlerBundle,
76    ProtocolStackSource,
77    ProtocolRelease,
78    ProtocolReleaseReview,
79    ProtocolResource,
80    ProviderSnapshot,
81    ExecutionIntent,
82}
83
84impl HashKindName {
85    pub const fn as_str(self) -> &'static str {
86        match self {
87            Self::IdlSource => "idl-source",
88            Self::IdlContent => "idl-content",
89            Self::IdlPortable => "idl-portable",
90            Self::IdlNormalized => "idl-normalized",
91            Self::ProgramSpec => "program-spec",
92            Self::AstPortable => "ast-portable",
93            Self::RuntimeArtifact => "runtime-artifact",
94            Self::ArtifactFile => "artifact-file",
95            Self::DecoderContent => "decoder-content",
96            Self::SdkDefinition => "sdk-definition",
97            Self::SdkExtension => "sdk-extension",
98            Self::SdkOutputTree => "sdk-output-tree",
99            Self::Compiler => "compiler",
100            Self::ProgramRelease => "program-release",
101            Self::LiveSpec => "live-spec",
102            Self::StackManifest => "stack-manifest",
103            Self::DeploymentRelease => "deployment-release",
104            Self::DecoderFixtureSet => "decoder-fixture-set",
105            Self::KnowledgeDocument => "knowledge-document",
106            Self::KnowledgeSnapshot => "knowledge-snapshot",
107            Self::ExtensionSurface => "extension-surface",
108            Self::SdkInstallTarget => "sdk-install-target",
109            Self::CatalogBundle => "catalog-bundle",
110            Self::CatalogPublicationSet => "catalog-publication-set",
111            Self::ProtocolSpec => "protocol-spec",
112            Self::ProtocolHandlerBundle => "protocol-handler-bundle",
113            Self::ProtocolStackSource => "protocol-stack-source",
114            Self::ProtocolRelease => "protocol-release",
115            Self::ProtocolReleaseReview => "protocol-release-review",
116            Self::ProtocolResource => "protocol-resource",
117            Self::ProviderSnapshot => "provider-snapshot",
118            Self::ExecutionIntent => "execution-intent",
119        }
120    }
121}
122
123impl fmt::Display for HashKindName {
124    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
125        formatter.write_str(self.as_str())
126    }
127}
128
129impl FromStr for HashKindName {
130    type Err = HashError;
131
132    fn from_str(value: &str) -> Result<Self, Self::Err> {
133        match value {
134            "idl-source" => Ok(Self::IdlSource),
135            "idl-content" => Ok(Self::IdlContent),
136            "idl-portable" => Ok(Self::IdlPortable),
137            "idl-normalized" => Ok(Self::IdlNormalized),
138            "program-spec" => Ok(Self::ProgramSpec),
139            "ast-portable" => Ok(Self::AstPortable),
140            "runtime-artifact" => Ok(Self::RuntimeArtifact),
141            "artifact-file" => Ok(Self::ArtifactFile),
142            "decoder-content" => Ok(Self::DecoderContent),
143            "sdk-definition" => Ok(Self::SdkDefinition),
144            "sdk-extension" => Ok(Self::SdkExtension),
145            "sdk-output-tree" => Ok(Self::SdkOutputTree),
146            "compiler" => Ok(Self::Compiler),
147            "program-release" => Ok(Self::ProgramRelease),
148            "live-spec" => Ok(Self::LiveSpec),
149            "stack-manifest" => Ok(Self::StackManifest),
150            "deployment-release" => Ok(Self::DeploymentRelease),
151            "decoder-fixture-set" => Ok(Self::DecoderFixtureSet),
152            "knowledge-document" => Ok(Self::KnowledgeDocument),
153            "knowledge-snapshot" => Ok(Self::KnowledgeSnapshot),
154            "extension-surface" => Ok(Self::ExtensionSurface),
155            "sdk-install-target" => Ok(Self::SdkInstallTarget),
156            "catalog-bundle" => Ok(Self::CatalogBundle),
157            "catalog-publication-set" => Ok(Self::CatalogPublicationSet),
158            "protocol-spec" => Ok(Self::ProtocolSpec),
159            "protocol-handler-bundle" => Ok(Self::ProtocolHandlerBundle),
160            "protocol-stack-source" => Ok(Self::ProtocolStackSource),
161            "protocol-release" => Ok(Self::ProtocolRelease),
162            "protocol-release-review" => Ok(Self::ProtocolReleaseReview),
163            "protocol-resource" => Ok(Self::ProtocolResource),
164            "provider-snapshot" => Ok(Self::ProviderSnapshot),
165            "execution-intent" => Ok(Self::ExecutionIntent),
166            _ => Err(HashError::UnknownKind(value.to_string())),
167        }
168    }
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
172#[serde(rename_all = "kebab-case")]
173pub enum Visibility {
174    Public,
175    AuthenticatedOwner,
176    InternalOnly,
177}
178
179#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
180#[serde(rename_all = "kebab-case")]
181pub enum IdentityClass {
182    ExactSource,
183    CanonicalContent,
184    PortableContent,
185    NormalizedContent,
186    Composite,
187    ArtifactTree,
188}
189
190#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
191#[serde(rename_all = "camelCase")]
192pub struct IdentityMetadata {
193    pub kind: HashKindName,
194    pub profile: CanonicalizationProfile,
195    pub visibility: Visibility,
196    pub identity_class: IdentityClass,
197    pub api_field: &'static str,
198    pub rust_type: &'static str,
199    pub typescript_type: &'static str,
200    pub projection: &'static str,
201    pub allowed_dto_audiences: &'static [Visibility],
202    pub database_mappings: &'static [&'static str],
203    pub legacy_aliases: &'static [&'static str],
204}
205
206#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
207#[serde(rename_all = "camelCase")]
208pub struct NonHashIdentityMetadata {
209    pub api_field: &'static str,
210    pub rust_type: &'static str,
211    pub typescript_type: &'static str,
212    pub projection: &'static str,
213    pub visibility: Visibility,
214    pub allowed_dto_audiences: &'static [Visibility],
215    pub database_mappings: &'static [&'static str],
216    pub legacy_aliases: &'static [&'static str],
217}
218
219const PUBLIC_DTO_AUDIENCES: &[Visibility] = &[
220    Visibility::Public,
221    Visibility::AuthenticatedOwner,
222    Visibility::InternalOnly,
223];
224const OWNER_DTO_AUDIENCES: &[Visibility] =
225    &[Visibility::AuthenticatedOwner, Visibility::InternalOnly];
226const INTERNAL_DTO_AUDIENCES: &[Visibility] = &[Visibility::InternalOnly];
227
228const fn allowed_dto_audiences(visibility: Visibility) -> &'static [Visibility] {
229    match visibility {
230        Visibility::Public => PUBLIC_DTO_AUDIENCES,
231        Visibility::AuthenticatedOwner => OWNER_DTO_AUDIENCES,
232        Visibility::InternalOnly => INTERNAL_DTO_AUDIENCES,
233    }
234}
235
236const fn api_field(kind: HashKindName) -> &'static str {
237    match kind {
238        HashKindName::IdlSource => "sourceIdlHash",
239        HashKindName::IdlContent => "idlContentHash",
240        HashKindName::IdlPortable => "portableIdlHash",
241        HashKindName::IdlNormalized => "normalizedIdlHash",
242        HashKindName::ProgramSpec => "programSpecHash",
243        HashKindName::AstPortable => "portableAstHash",
244        HashKindName::RuntimeArtifact => "runtimeArtifactHash",
245        HashKindName::ArtifactFile => "artifactFileHash",
246        HashKindName::DecoderContent => "decoderContentHash",
247        HashKindName::SdkDefinition => "sdkDefinitionHash",
248        HashKindName::SdkExtension => "sdkExtensionHash",
249        HashKindName::SdkOutputTree => "sdkOutputTreeHash",
250        HashKindName::Compiler => "compilerHash",
251        HashKindName::ProgramRelease => "programReleaseHash",
252        HashKindName::LiveSpec => "liveSpecHash",
253        HashKindName::StackManifest => "stackManifestHash",
254        HashKindName::DeploymentRelease => "deploymentReleaseHash",
255        HashKindName::DecoderFixtureSet => "decoderFixtureSetHash",
256        HashKindName::KnowledgeDocument => "documentHash",
257        HashKindName::KnowledgeSnapshot => "knowledgeSnapshotHash",
258        HashKindName::ExtensionSurface => "surfaceHash",
259        HashKindName::SdkInstallTarget => "sdkInstallTargetHash",
260        HashKindName::CatalogBundle => "bundleHash",
261        HashKindName::CatalogPublicationSet => "setHash",
262        HashKindName::ProtocolSpec => "protocolSpecHash",
263        HashKindName::ProtocolHandlerBundle => "handlerBundleHash",
264        HashKindName::ProtocolStackSource => "protocolStackSourceHash",
265        HashKindName::ProtocolRelease => "protocolReleaseHash",
266        HashKindName::ProtocolReleaseReview => "reviewHash",
267        HashKindName::ProtocolResource => "resourceHash",
268        HashKindName::ProviderSnapshot => "providerSnapshotHash",
269        HashKindName::ExecutionIntent => "executionIntentHash",
270    }
271}
272
273const fn rust_type(kind: HashKindName) -> &'static str {
274    match kind {
275        HashKindName::IdlSource => "HashId<IdlSource>",
276        HashKindName::IdlContent => "HashId<IdlContent>",
277        HashKindName::IdlPortable => "HashId<IdlPortable>",
278        HashKindName::IdlNormalized => "HashId<IdlNormalized>",
279        HashKindName::ProgramSpec => "HashId<ProgramSpec>",
280        HashKindName::AstPortable => "HashId<AstPortable>",
281        HashKindName::RuntimeArtifact => "HashId<RuntimeArtifact>",
282        HashKindName::ArtifactFile => "HashId<ArtifactFile>",
283        HashKindName::DecoderContent => "HashId<DecoderContent>",
284        HashKindName::SdkDefinition => "HashId<SdkDefinition>",
285        HashKindName::SdkExtension => "HashId<SdkExtension>",
286        HashKindName::SdkOutputTree => "HashId<SdkOutputTree>",
287        HashKindName::Compiler => "HashId<Compiler>",
288        HashKindName::ProgramRelease => "HashId<ProgramRelease>",
289        HashKindName::LiveSpec => "HashId<LiveSpec>",
290        HashKindName::StackManifest => "HashId<StackManifest>",
291        HashKindName::DeploymentRelease => "HashId<DeploymentRelease>",
292        HashKindName::DecoderFixtureSet => "HashId<DecoderFixtureSet>",
293        HashKindName::KnowledgeDocument => "HashId<KnowledgeDocument>",
294        HashKindName::KnowledgeSnapshot => "HashId<KnowledgeSnapshot>",
295        HashKindName::ExtensionSurface => "HashId<ExtensionSurface>",
296        HashKindName::SdkInstallTarget => "HashId<SdkInstallTarget>",
297        HashKindName::CatalogBundle => "HashId<CatalogBundle>",
298        HashKindName::CatalogPublicationSet => "HashId<CatalogPublicationSet>",
299        HashKindName::ProtocolSpec => "HashId<ProtocolSpec>",
300        HashKindName::ProtocolHandlerBundle => "HashId<ProtocolHandlerBundle>",
301        HashKindName::ProtocolStackSource => "HashId<ProtocolStackSource>",
302        HashKindName::ProtocolRelease => "HashId<ProtocolRelease>",
303        HashKindName::ProtocolReleaseReview => "HashId<ProtocolReleaseReview>",
304        HashKindName::ProtocolResource => "HashId<ProtocolResource>",
305        HashKindName::ProviderSnapshot => "HashId<ProviderSnapshot>",
306        HashKindName::ExecutionIntent => "HashId<ExecutionIntent>",
307    }
308}
309
310const fn typescript_type(kind: HashKindName) -> &'static str {
311    match kind {
312        HashKindName::IdlSource => "IdlSourceHash",
313        HashKindName::IdlContent => "IdlContentHash",
314        HashKindName::IdlPortable => "IdlPortableHash",
315        HashKindName::IdlNormalized => "IdlNormalizedHash",
316        HashKindName::ProgramSpec => "ProgramSpecHash",
317        HashKindName::AstPortable => "AstPortableHash",
318        HashKindName::RuntimeArtifact => "RuntimeArtifactHash",
319        HashKindName::ArtifactFile => "ArtifactFileHash",
320        HashKindName::DecoderContent => "DecoderContentHash",
321        HashKindName::SdkDefinition => "SdkDefinitionHash",
322        HashKindName::SdkExtension => "SdkExtensionHash",
323        HashKindName::SdkOutputTree => "SdkOutputTreeHash",
324        HashKindName::Compiler => "CompilerHash",
325        HashKindName::ProgramRelease => "ProgramReleaseHash",
326        HashKindName::LiveSpec => "LiveSpecHash",
327        HashKindName::StackManifest => "StackManifestHash",
328        HashKindName::DeploymentRelease => "DeploymentReleaseHash",
329        HashKindName::DecoderFixtureSet => "DecoderFixtureSetHash",
330        HashKindName::KnowledgeDocument => "KnowledgeDocumentHash",
331        HashKindName::KnowledgeSnapshot => "KnowledgeSnapshotHash",
332        HashKindName::ExtensionSurface => "ExtensionSurfaceHash",
333        HashKindName::SdkInstallTarget => "SdkInstallTargetHash",
334        HashKindName::CatalogBundle => "CatalogBundleHash",
335        HashKindName::CatalogPublicationSet => "CatalogPublicationSetHash",
336        HashKindName::ProtocolSpec => "ProtocolSpecHash",
337        HashKindName::ProtocolHandlerBundle => "ProtocolHandlerBundleHash",
338        HashKindName::ProtocolStackSource => "ProtocolStackSourceHash",
339        HashKindName::ProtocolRelease => "ProtocolReleaseHash",
340        HashKindName::ProtocolReleaseReview => "ProtocolReleaseReviewHash",
341        HashKindName::ProtocolResource => "ProtocolResourceHash",
342        HashKindName::ProviderSnapshot => "ProviderSnapshotHash",
343        HashKindName::ExecutionIntent => "ExecutionIntentHash",
344    }
345}
346
347const fn projection(kind: HashKindName) -> &'static str {
348    match kind {
349        HashKindName::IdlSource => "arete.idl-source/exact-bytes-v1",
350        HashKindName::IdlContent => "arete.idl-content/source-json-v1",
351        HashKindName::IdlPortable => "arete.idl-portable/source-json-v1",
352        HashKindName::IdlNormalized => "arete.idl-normalized/v1",
353        HashKindName::ProgramSpec => "arete.program-spec/v1",
354        HashKindName::AstPortable => "arete.ast-portable/self-hash-v1",
355        HashKindName::RuntimeArtifact => "arete.runtime-artifact/v1",
356        HashKindName::ArtifactFile => "arete.artifact-file/exact-bytes-v1",
357        HashKindName::DecoderContent => "arete.decoder-content/exact-bytes-v1",
358        HashKindName::SdkDefinition => "arete.sdk-definition/v1",
359        HashKindName::SdkExtension => "arete.sdk-extension/v1",
360        HashKindName::SdkOutputTree => "arete.sdk-output-tree/artifact-tree-v1",
361        HashKindName::Compiler => "arete.compiler/v1",
362        HashKindName::ProgramRelease => "arete.program-release/v1",
363        HashKindName::LiveSpec => "arete.artifact-envelope/live-spec-v1",
364        HashKindName::StackManifest => "arete.artifact-envelope/stack-manifest-v1",
365        HashKindName::DeploymentRelease => "arete.deployment-release/v1",
366        HashKindName::DecoderFixtureSet => "arete.decoder-fixtures/v2",
367        HashKindName::KnowledgeDocument => "arete.knowledge-document/v1",
368        HashKindName::KnowledgeSnapshot => "arete.knowledge-snapshot/v1",
369        HashKindName::ExtensionSurface => "arete.extension-surface/v2",
370        HashKindName::SdkInstallTarget => "arete.sdk-install-target/v1",
371        HashKindName::CatalogBundle => "arete.catalog-bundle/v1",
372        HashKindName::CatalogPublicationSet => "arete.catalog-publication-set/v1",
373        HashKindName::ProtocolSpec => "arete.protocol-spec/v1",
374        HashKindName::ProtocolHandlerBundle => "arete.protocol-handler-bundle/exact-bytes-v1",
375        HashKindName::ProtocolStackSource => "arete.protocol-stack-source/v1",
376        HashKindName::ProtocolRelease => "arete.protocol-release/v1",
377        HashKindName::ProtocolReleaseReview => "arete.protocol-release-review/v1",
378        HashKindName::ProtocolResource => "arete.protocol-resource/v1",
379        HashKindName::ProviderSnapshot => "arete.provider-snapshot/v1",
380        HashKindName::ExecutionIntent => "arete.execution-intent/v1",
381    }
382}
383
384const fn database_mappings(kind: HashKindName) -> &'static [&'static str] {
385    match kind {
386        HashKindName::IdlSource | HashKindName::ArtifactFile => &[],
387        HashKindName::IdlContent => &[
388            "idl_contents.idl_content_hash",
389            "program_releases.idl_content_hash",
390        ],
391        HashKindName::IdlPortable => &["idl_contents.idl_portable_hash"],
392        HashKindName::IdlNormalized => &[
393            "idl_contents.idl_normalized_hash",
394            "decoder_bindings.normalized_idl_hash",
395            "program_releases.normalized_idl_hash",
396            "decoder_fixture_sets.normalized_idl_hash",
397        ],
398        HashKindName::ProgramSpec => &[
399            "idl_contents.program_spec_hash",
400            "program_spec_artifacts.program_spec_hash",
401            "program_releases.program_spec_hash",
402        ],
403        HashKindName::AstPortable => &[
404            "ast_contents.ast_portable_hash",
405            "builds.ast_portable_hash",
406            "deployments.current_ast_portable_hash",
407        ],
408        HashKindName::RuntimeArtifact => &[
409            "runtime_artifacts.runtime_artifact_hash",
410            "builds.runtime_artifact_hash",
411        ],
412        HashKindName::DecoderContent => &[
413            "decoder_contents.content_hash",
414            "decoder_executions.decoder_content_hash",
415        ],
416        HashKindName::SdkDefinition | HashKindName::Compiler => &[],
417        HashKindName::SdkExtension => &["sdk_extension_contents.sdk_extension_hash"],
418        HashKindName::SdkOutputTree => &["sdk_extension_contents.sdk_output_tree_hash"],
419        HashKindName::ProgramRelease => &["program_releases.release_hash"],
420        HashKindName::LiveSpec => &["live_spec_artifacts.live_spec_hash"],
421        HashKindName::StackManifest => &["stack_manifest_artifacts.stack_manifest_hash"],
422        HashKindName::DeploymentRelease => &[
423            "deployment_releases.deployment_release_hash",
424            "builds.deployment_release_hash",
425            "deployments.deployment_release_hash",
426        ],
427        HashKindName::DecoderFixtureSet => &["decoder_fixture_sets.fixture_set_hash"],
428        HashKindName::KnowledgeDocument => &[
429            "knowledge_document_artifacts.document_hash",
430            "knowledge_snapshot_documents.document_hash",
431            "catalog_bundle_documents.document_hash",
432        ],
433        HashKindName::KnowledgeSnapshot => &[
434            "knowledge_snapshot_artifacts.snapshot_hash",
435            "catalog_publication_sets.knowledge_snapshot_hash",
436        ],
437        HashKindName::ExtensionSurface => &[
438            "extension_surface_artifacts_v2.surface_hash",
439            "sdk_install_target_artifacts.surface_hash",
440            "catalog_bundle_surfaces.surface_hash",
441        ],
442        HashKindName::SdkInstallTarget => &[
443            "sdk_install_target_artifacts.sdk_install_target_hash",
444            "registry_package_sdk_targets.sdk_install_target_hash",
445            "catalog_bundle_sdk_targets.sdk_install_target_hash",
446        ],
447        HashKindName::CatalogBundle => &[
448            "catalog_bundles.bundle_hash",
449            "catalog_publication_set_entries.bundle_hash",
450        ],
451        HashKindName::CatalogPublicationSet => &[
452            "catalog_publication_sets.set_hash",
453            "catalog_active_sets.set_hash",
454            "catalog_publication_events.set_hash",
455        ],
456        HashKindName::ProtocolSpec => &["protocol_specs.spec_hash", "protocol_releases.spec_hash"],
457        HashKindName::ProtocolHandlerBundle => &[
458            "protocol_handler_bundles.bundle_hash",
459            "protocol_releases.bundle_hash",
460        ],
461        HashKindName::ProtocolStackSource => &[
462            "protocol_stack_sources.stack_source_hash",
463            "protocol_releases.stack_source_hash",
464        ],
465        HashKindName::ProtocolRelease => &[
466            "protocol_releases.release_hash",
467            "protocol_release_reviews.release_hash",
468            "protocol_deployment_revisions.release_hash",
469        ],
470        HashKindName::ProtocolReleaseReview => &["protocol_release_reviews.review_hash"],
471        HashKindName::ProtocolResource => &["protocol_resource_versions.resource_hash"],
472        HashKindName::ProviderSnapshot => &["protocol_execution_intents.provider_snapshot_hash"],
473        HashKindName::ExecutionIntent => &["protocol_execution_intents.intent_hash"],
474    }
475}
476
477const fn legacy_aliases(kind: HashKindName) -> &'static [&'static str] {
478    match kind {
479        HashKindName::IdlContent => &["legacy_idl_json_sha256"],
480        HashKindName::IdlPortable => &["legacy_idl_json_no_program_sha256"],
481        HashKindName::IdlNormalized => &["legacy_normalized_idl_sha256"],
482        HashKindName::AstPortable => &["legacy_portable_ast_sha256"],
483        HashKindName::RuntimeArtifact => &["legacy_platform_ast_sha256"],
484        HashKindName::DecoderContent => &["legacy_decoder_content_sha256"],
485        HashKindName::SdkExtension => &["legacy_sdk_extension_sha256"],
486        _ => &[],
487    }
488}
489
490mod sealed {
491    pub trait Sealed {}
492}
493
494pub trait Kind: sealed::Sealed + 'static {
495    const NAME: HashKindName;
496    const PROFILE: CanonicalizationProfile;
497    const VISIBILITY: Visibility;
498    const IDENTITY_CLASS: IdentityClass;
499}
500
501macro_rules! define_kinds {
502    ($(($type:ident, $name:ident, $profile:ident, $visibility:ident, $class:ident)),+ $(,)?) => {
503        $(
504            #[derive(Debug)]
505            pub struct $type;
506
507            impl sealed::Sealed for $type {}
508
509            impl Kind for $type {
510                const NAME: HashKindName = HashKindName::$name;
511                const PROFILE: CanonicalizationProfile = CanonicalizationProfile::$profile;
512                const VISIBILITY: Visibility = Visibility::$visibility;
513                const IDENTITY_CLASS: IdentityClass = IdentityClass::$class;
514            }
515        )+
516
517        pub const IDENTITY_REGISTRY: &[IdentityMetadata] = &[
518            $(IdentityMetadata {
519                kind: HashKindName::$name,
520                profile: CanonicalizationProfile::$profile,
521                visibility: Visibility::$visibility,
522                identity_class: IdentityClass::$class,
523                api_field: api_field(HashKindName::$name),
524                rust_type: rust_type(HashKindName::$name),
525                typescript_type: typescript_type(HashKindName::$name),
526                projection: projection(HashKindName::$name),
527                allowed_dto_audiences: allowed_dto_audiences(Visibility::$visibility),
528                database_mappings: database_mappings(HashKindName::$name),
529                legacy_aliases: legacy_aliases(HashKindName::$name),
530            }),+
531        ];
532    };
533}
534
535define_kinds!(
536    (IdlSource, IdlSource, RawBytesV1, Public, ExactSource),
537    (IdlContent, IdlContent, AreteJcsV1, Public, CanonicalContent),
538    (
539        IdlPortable,
540        IdlPortable,
541        AreteJcsV1,
542        Public,
543        PortableContent
544    ),
545    (
546        IdlNormalized,
547        IdlNormalized,
548        AreteJcsV1,
549        Public,
550        NormalizedContent
551    ),
552    (ProgramSpec, ProgramSpec, AreteJcsV1, Public, Composite),
553    (
554        AstPortable,
555        AstPortable,
556        AreteJcsV1,
557        Public,
558        PortableContent
559    ),
560    (
561        RuntimeArtifact,
562        RuntimeArtifact,
563        AreteJcsV1,
564        InternalOnly,
565        Composite
566    ),
567    (
568        ArtifactFile,
569        ArtifactFile,
570        RawBytesV1,
571        Public,
572        CanonicalContent
573    ),
574    (
575        DecoderContent,
576        DecoderContent,
577        RawBytesV1,
578        InternalOnly,
579        CanonicalContent
580    ),
581    (SdkDefinition, SdkDefinition, AreteJcsV1, Public, Composite),
582    (SdkExtension, SdkExtension, AreteJcsV1, Public, Composite),
583    (
584        SdkOutputTree,
585        SdkOutputTree,
586        ArtifactTreeV1,
587        Public,
588        ArtifactTree
589    ),
590    (Compiler, Compiler, FramedTupleV1, Public, Composite),
591    (
592        ProgramRelease,
593        ProgramRelease,
594        AreteJcsV1,
595        Public,
596        Composite
597    ),
598    (LiveSpec, LiveSpec, AreteJcsV1, Public, Composite),
599    (StackManifest, StackManifest, AreteJcsV1, Public, Composite),
600    (
601        DeploymentRelease,
602        DeploymentRelease,
603        AreteJcsV1,
604        AuthenticatedOwner,
605        Composite
606    ),
607    (
608        DecoderFixtureSet,
609        DecoderFixtureSet,
610        AreteJcsV1,
611        InternalOnly,
612        Composite
613    ),
614    (
615        KnowledgeDocument,
616        KnowledgeDocument,
617        AreteJcsV1,
618        Public,
619        CanonicalContent
620    ),
621    (
622        KnowledgeSnapshot,
623        KnowledgeSnapshot,
624        AreteJcsV1,
625        Public,
626        Composite
627    ),
628    (
629        ExtensionSurface,
630        ExtensionSurface,
631        AreteJcsV1,
632        Public,
633        Composite
634    ),
635    (
636        SdkInstallTarget,
637        SdkInstallTarget,
638        AreteJcsV1,
639        Public,
640        Composite
641    ),
642    (CatalogBundle, CatalogBundle, AreteJcsV1, Public, Composite),
643    (
644        CatalogPublicationSet,
645        CatalogPublicationSet,
646        AreteJcsV1,
647        Public,
648        Composite
649    ),
650    (ProtocolSpec, ProtocolSpec, AreteJcsV1, Public, Composite),
651    (
652        ProtocolHandlerBundle,
653        ProtocolHandlerBundle,
654        RawBytesV1,
655        Public,
656        CanonicalContent
657    ),
658    (
659        ProtocolStackSource,
660        ProtocolStackSource,
661        AreteJcsV1,
662        Public,
663        Composite
664    ),
665    (
666        ProtocolRelease,
667        ProtocolRelease,
668        AreteJcsV1,
669        Public,
670        Composite
671    ),
672    (
673        ProtocolReleaseReview,
674        ProtocolReleaseReview,
675        AreteJcsV1,
676        Public,
677        Composite
678    ),
679    (
680        ProtocolResource,
681        ProtocolResource,
682        AreteJcsV1,
683        AuthenticatedOwner,
684        Composite
685    ),
686    (
687        ProviderSnapshot,
688        ProviderSnapshot,
689        AreteJcsV1,
690        AuthenticatedOwner,
691        Composite
692    ),
693    (
694        ExecutionIntent,
695        ExecutionIntent,
696        AreteJcsV1,
697        AuthenticatedOwner,
698        Composite
699    ),
700);
701
702pub const NON_HASH_IDENTITY_REGISTRY: &[NonHashIdentityMetadata] = &[
703    NonHashIdentityMetadata {
704        api_field: "programReadBindingId",
705        rust_type: "ProgramReadBindingId",
706        typescript_type: "ProgramReadBindingId",
707        projection: "arete.program-read-binding/v1",
708        visibility: Visibility::Public,
709        allowed_dto_audiences: PUBLIC_DTO_AUDIENCES,
710        database_mappings: &[
711            "program_read_bindings.id",
712            "program_read_routes.program_read_binding_id",
713            "program_read_usage_events.program_read_binding_id",
714        ],
715        legacy_aliases: &[],
716    },
717    NonHashIdentityMetadata {
718        api_field: "decoderBindingId",
719        rust_type: "internal::DecoderBindingId",
720        typescript_type: "DecoderBindingId",
721        projection: "arete.decoder-binding/v1",
722        visibility: Visibility::InternalOnly,
723        allowed_dto_audiences: INTERNAL_DTO_AUDIENCES,
724        database_mappings: &["decoder_bindings.id", "program_releases.decoder_binding_id"],
725        legacy_aliases: &[],
726    },
727    NonHashIdentityMetadata {
728        api_field: "decoderEngineId",
729        rust_type: "internal::DecoderEngineId",
730        typescript_type: "DecoderEngineId",
731        projection: "arete.decoder-engine/v1",
732        visibility: Visibility::InternalOnly,
733        allowed_dto_audiences: INTERNAL_DTO_AUDIENCES,
734        database_mappings: &[
735            "decoder_executions.decoder_engine_id",
736            "program_releases.decoder_engine_id",
737            "decoder_fixture_sets.decoder_engine_id",
738        ],
739        legacy_aliases: &[],
740    },
741];
742
743pub fn identity_metadata(kind: HashKindName) -> &'static IdentityMetadata {
744    IDENTITY_REGISTRY
745        .iter()
746        .find(|metadata| metadata.kind == kind)
747        .expect("closed hash kind registry is exhaustive")
748}