use llvm_support::bitcodes::{IdentificationCode, IrBlockId};
use thiserror::Error;
use crate::block::IrBlock;
use crate::map::{MapError, PartialMapCtx};
use crate::unroll::UnrolledBlock;
#[derive(Debug, Error)]
pub enum IdentificationError {
#[error("identification block has no producer")]
MissingProducer,
#[error("malformed producer string")]
BadProducer,
#[error("identification block has no epoch")]
MissingEpoch,
#[error("mapping error in string table")]
Map(#[from] MapError),
}
#[non_exhaustive]
#[derive(Debug)]
pub struct Identification {
pub producer: String,
pub epoch: u64,
}
impl IrBlock for Identification {
type Error = IdentificationError;
const BLOCK_ID: IrBlockId = IrBlockId::Identification;
fn try_map_inner(block: &UnrolledBlock, _ctx: &mut PartialMapCtx) -> Result<Self, Self::Error> {
let producer = block
.records()
.one(IdentificationCode::ProducerString as u64)
.ok_or(IdentificationError::MissingProducer)
.and_then(|r| {
r.try_string(0)
.map_err(|_| IdentificationError::BadProducer)
})?;
let epoch = *block
.records()
.one(IdentificationCode::Epoch as u64)
.ok_or(IdentificationError::MissingEpoch)
.and_then(|r| r.fields().get(0).ok_or(IdentificationError::MissingEpoch))?;
Ok(Self { producer, epoch })
}
}