use crate::metadata::Metadata;
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub const DEBUGINFO_META_KEY: &str = "core.debug_info";
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum DebugInfoError {
#[error("Debug metadata has wrong kind: got '{0}' expected '{1}'")]
DRKindMismatchError(String, &'static str),
}
pub trait DebugRecordKind {
fn check_kind(&self) -> Result<(), DebugInfoError>;
}
macro_rules! impl_dr_kind_check {
( $drtype:ty, $expected_kind:expr ) => {
impl DebugRecordKind for $drtype {
fn check_kind(&self) -> Result<(), DebugInfoError> {
if &self.kind == $expected_kind {
Ok(())
} else {
Err(DebugInfoError::DRKindMismatchError(
self.kind.clone(),
$expected_kind,
))
}
}
}
};
}
#[derive(Serialize, Deserialize)]
pub struct CompileUnitRecord {
pub kind: String,
pub directory: String,
pub filename: usize,
pub file_table: Vec<String>,
}
impl Metadata for CompileUnitRecord {
type Type<'hugr> = CompileUnitRecord;
const KEY: &'static str = DEBUGINFO_META_KEY;
}
impl_dr_kind_check!(CompileUnitRecord, "compile_unit");
#[derive(Serialize, Deserialize)]
pub struct SubprogramRecord {
pub kind: String,
pub file: usize,
pub line_no: usize,
pub scope_line: usize,
}
impl Metadata for SubprogramRecord {
type Type<'hugr> = SubprogramRecord;
const KEY: &'static str = DEBUGINFO_META_KEY;
}
impl_dr_kind_check!(SubprogramRecord, "subprogram");
#[derive(Serialize, Deserialize)]
pub struct LocationRecord {
pub kind: String,
pub column: usize,
pub line_no: usize,
}
impl Metadata for LocationRecord {
type Type<'hugr> = LocationRecord;
const KEY: &'static str = DEBUGINFO_META_KEY;
}
impl_dr_kind_check!(LocationRecord, "location");