zksync_error/
identifier.rsuse crate::error::domains::AnvilZksyncCode;
use crate::error::domains::CompilerCode;
use crate::error::domains::CoreCode;
use crate::error::domains::FoundryCode;
use crate::error::domains::HardhatCode;
use crate::error::NamedError;
use crate::kind::DomainCode;
use crate::kind::Kind;
#[derive(Clone, Debug, Eq, PartialEq, serde :: Deserialize, serde :: Serialize)]
pub struct StructuredErrorCode {
pub domain_code: u32,
pub component_code: u32,
pub error_code: u32,
}
impl StructuredErrorCode {
pub fn encode(&self) -> u32 {
self.domain_code * 10000 + self.component_code * 1000 + self.error_code
}
pub fn decode(raw_code: u32) -> Self {
let error_code = raw_code % 1000;
let component_code = (raw_code / 1000) % 10;
let domain_code = (raw_code / 10000) % 10;
StructuredErrorCode {
domain_code,
component_code,
error_code,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, serde :: Deserialize, serde :: Serialize)]
pub struct Identifier {
pub kind: Kind,
pub code: u32,
}
impl Identifier {
pub fn new(kind: Kind, code: u32) -> Self {
Self { kind, code }
}
pub fn encode(&self) -> u32 {
let domain_code: u32 = self.kind.domain_code();
let component_code: u32 = self.kind.component_code();
domain_code * 10000 + component_code * 1000 + self.code
}
pub fn decode(code: StructuredErrorCode) -> Option<Self> {
let StructuredErrorCode {
domain_code,
component_code,
error_code,
} = code;
let domain = DomainCode::from_repr(domain_code)?;
let kind: Kind = match domain {
DomainCode::AnvilZksync => {
Kind::AnvilZksync(AnvilZksyncCode::from_repr(component_code)?)
}
DomainCode::Compiler => Kind::Compiler(CompilerCode::from_repr(component_code)?),
DomainCode::Core => Kind::Core(CoreCode::from_repr(component_code)?),
DomainCode::Foundry => Kind::Foundry(FoundryCode::from_repr(component_code)?),
DomainCode::Hardhat => Kind::Hardhat(HardhatCode::from_repr(component_code)?),
};
Some(Identifier {
kind,
code: error_code,
})
}
}
pub trait Identifying {
fn get_identifier_repr(&self) -> String;
}
impl Identifying for Identifier {
fn get_identifier_repr(&self) -> String {
format!("[{}-{}]", self.kind.get_identifier_repr(), self.code)
}
}
impl Identifying for Kind {
fn get_identifier_repr(&self) -> String {
match self {
Kind::AnvilZksync(AnvilZksyncCode::AnvilEnvironment) => "anvil_zksync-env",
Kind::AnvilZksync(AnvilZksyncCode::AnvilGeneric) => "anvil_zksync-gen",
Kind::AnvilZksync(AnvilZksyncCode::Halt) => "anvil_zksync-halt",
Kind::AnvilZksync(AnvilZksyncCode::Revert) => "anvil_zksync-revert",
Kind::Compiler(CompilerCode::LLVM_EVM) => "compiler-llvm+evm",
Kind::Compiler(CompilerCode::LLVM_Era) => "compiler-llvm+era",
Kind::Compiler(CompilerCode::Solc) => "compiler-solc",
Kind::Compiler(CompilerCode::SolcFork) => "compiler-solc+fork",
Kind::Compiler(CompilerCode::Zksolc) => "compiler-zksolc",
Kind::Compiler(CompilerCode::Zkvyper) => "compiler-zkvyper",
Kind::Core(CoreCode::API) => "core-api",
Kind::Core(CoreCode::EraVM) => "core-eravm",
Kind::Core(CoreCode::ExecutionPlatform) => "core-exec",
Kind::Core(CoreCode::Sequencer) => "core-seq",
Kind::Foundry(FoundryCode::FoundryUpstream) => "foundry-upstream",
Kind::Foundry(FoundryCode::FoundryZksync) => "foundry-zksync",
Kind::Hardhat(HardhatCode::HardhatUpstream) => "hardhat-upstream",
Kind::Hardhat(HardhatCode::HardhatZksync) => "hardhat-zksync",
}
.into()
}
}
impl NamedError for Identifier {
fn get_error_name(&self) -> String {
match self.kind {
Kind::AnvilZksync(AnvilZksyncCode::AnvilEnvironment) => {
crate::error::definitions::AnvilEnvironmentCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::AnvilZksync(AnvilZksyncCode::AnvilGeneric) => {
crate::error::definitions::AnvilGenericCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::AnvilZksync(AnvilZksyncCode::Halt) => {
crate::error::definitions::HaltCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::AnvilZksync(AnvilZksyncCode::Revert) => {
crate::error::definitions::RevertCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Compiler(CompilerCode::LLVM_EVM) => {
crate::error::definitions::LLVM_EVMCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Compiler(CompilerCode::LLVM_Era) => {
crate::error::definitions::LLVM_EraCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Compiler(CompilerCode::Solc) => {
crate::error::definitions::SolcCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Compiler(CompilerCode::SolcFork) => {
crate::error::definitions::SolcForkCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Compiler(CompilerCode::Zksolc) => {
crate::error::definitions::ZksolcCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Compiler(CompilerCode::Zkvyper) => {
crate::error::definitions::ZkvyperCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Core(CoreCode::API) => crate::error::definitions::APICode::from_repr(self.code)
.expect("Internal error")
.get_error_name(),
Kind::Core(CoreCode::EraVM) => {
crate::error::definitions::EraVMCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Core(CoreCode::ExecutionPlatform) => {
crate::error::definitions::ExecutionPlatformCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Core(CoreCode::Sequencer) => {
crate::error::definitions::SequencerCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Foundry(FoundryCode::FoundryUpstream) => {
crate::error::definitions::FoundryUpstreamCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Foundry(FoundryCode::FoundryZksync) => {
crate::error::definitions::FoundryZksyncCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Hardhat(HardhatCode::HardhatUpstream) => {
crate::error::definitions::HardhatUpstreamCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
Kind::Hardhat(HardhatCode::HardhatZksync) => {
crate::error::definitions::HardhatZksyncCode::from_repr(self.code)
.expect("Internal error")
.get_error_name()
}
}
}
}
impl crate::documentation::Documented for Identifier {
type Documentation = &'static zksync_error_description::ErrorDocumentation;
fn get_documentation(
&self,
) -> Result<Option<Self::Documentation>, crate::documentation::DocumentationError> {
use crate::documentation::model;
let repr = &self.get_identifier_repr();
match model.errors.get(repr) {
Some(metadata) => Ok(metadata.documentation.as_ref()),
None => Err(crate::documentation::DocumentationError::IncompleteModel(
format!("Can not fetch description for error {repr}."),
)),
}
}
}