1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum HashError {
5 #[error("invalid hash identifier: {0}")]
6 InvalidHashId(&'static str),
7 #[error("unknown hash protocol version '{0}'")]
8 UnknownVersion(String),
9 #[error("unknown hash kind '{0}'")]
10 UnknownKind(String),
11 #[error("expected hash kind '{expected}', got '{actual}'")]
12 UnexpectedKind { expected: String, actual: String },
13 #[error("unknown hash algorithm '{0}'")]
14 UnknownAlgorithm(String),
15 #[error("hash kind '{kind}' requires profile '{expected}', not '{actual}'")]
16 ProfileMismatch {
17 kind: String,
18 expected: String,
19 actual: String,
20 },
21 #[error("invalid JSON: {0}")]
22 InvalidJson(String),
23 #[error("duplicate JSON object key '{0}'")]
24 DuplicateJsonKey(String),
25 #[error("unsafe JSON integer '{0}'")]
26 UnsafeJsonInteger(String),
27 #[error("non-finite JSON numbers are not supported")]
28 NonFiniteNumber,
29 #[error("tuple labels must be unique: '{0}'")]
30 DuplicateTupleLabel(String),
31 #[error("invalid artifact path '{path}': {reason}")]
32 InvalidArtifactPath { path: String, reason: &'static str },
33 #[error("duplicate artifact path '{0}'")]
34 DuplicateArtifactPath(String),
35 #[error("artifact tree entries cannot be symlinks: '{0}'")]
36 SymlinkArtifact(String),
37 #[error("self-hash projection must be a JSON object")]
38 InvalidSelfHashProjection,
39 #[error("invalid {projection} projection: {reason}")]
40 InvalidProjection {
41 projection: &'static str,
42 reason: String,
43 },
44 #[error("program ID is missing from the IDL and no explicit program ID was supplied")]
45 MissingProgramId,
46 #[error("program ID at '{location}' must be a string or null")]
47 InvalidProgramIdLocation { location: &'static str },
48 #[error("conflicting program IDs: {0}")]
49 ConflictingProgramIds(String),
50 #[error("failed to parse IDL: {0}")]
51 InvalidIdl(String),
52 #[error("serialization failed: {0}")]
53 Serialization(String),
54}
55
56impl HashError {
57 pub fn code(&self) -> &'static str {
59 match self {
60 Self::InvalidHashId(_) => "invalid-hash-id",
61 Self::UnknownVersion(_) => "unknown-version",
62 Self::UnknownKind(_) => "unknown-kind",
63 Self::UnexpectedKind { .. } => "unexpected-kind",
64 Self::UnknownAlgorithm(_) => "unknown-algorithm",
65 Self::ProfileMismatch { .. } => "profile-mismatch",
66 Self::InvalidJson(_) => "invalid-json",
67 Self::DuplicateJsonKey(_) => "duplicate-json-key",
68 Self::UnsafeJsonInteger(_) => "unsafe-json-integer",
69 Self::NonFiniteNumber => "non-finite-number",
70 Self::DuplicateTupleLabel(_) => "duplicate-tuple-label",
71 Self::InvalidArtifactPath { .. } => "invalid-artifact-path",
72 Self::DuplicateArtifactPath(_) => "duplicate-artifact-path",
73 Self::SymlinkArtifact(_) => "symlink-artifact",
74 Self::InvalidSelfHashProjection => "invalid-self-hash-projection",
75 Self::InvalidProjection { .. } => "invalid-projection",
76 Self::MissingProgramId => "missing-program-id",
77 Self::InvalidProgramIdLocation { .. } => "invalid-program-id-location",
78 Self::ConflictingProgramIds(_) => "conflicting-program-ids",
79 Self::InvalidIdl(_) => "invalid-idl",
80 Self::Serialization(_) => "serialization",
81 }
82 }
83}
84
85impl From<serde_json::Error> for HashError {
86 fn from(error: serde_json::Error) -> Self {
87 Self::Serialization(error.to_string())
88 }
89}