use crate::renderer::{RenderContext, RenderFilterMode};
use daml_lf::element::{DamlArchive, DamlData, DamlKind, DamlTyCon, DamlType};
pub struct IsRenderable<'a> {
archive: &'a DamlArchive<'a>,
filter_mode: RenderFilterMode,
}
impl<'a> IsRenderable<'a> {
pub const fn new(ctx: &'a RenderContext<'a>) -> Self {
Self {
archive: ctx.archive(),
filter_mode: ctx.filter_mode(),
}
}
pub fn check_type(&self, ty: &DamlType<'_>) -> bool {
match ty {
DamlType::Int64
| DamlType::Text
| DamlType::Timestamp
| DamlType::Party
| DamlType::Bool
| DamlType::Unit
| DamlType::Date
| DamlType::Nat(_) => true,
DamlType::List(args)
| DamlType::TextMap(args)
| DamlType::GenMap(args)
| DamlType::Optional(args)
| DamlType::Numeric(args) => args.iter().all(|arg| self.check_type(arg)),
DamlType::ContractId(tycon) => tycon.as_ref().map_or(true, |ty| self.check_type(ty)),
DamlType::TyCon(tycon) | DamlType::BoxedTyCon(tycon) => self.check_tycon(tycon),
DamlType::Var(var) => var.type_arguments().iter().all(|ty| self.check_type(ty)),
DamlType::Arrow
| DamlType::Update
| DamlType::Scenario
| DamlType::Any
| DamlType::TypeRep
| DamlType::Bignumeric
| DamlType::RoundingMode
| DamlType::AnyException
| DamlType::Forall(_)
| DamlType::Struct(_)
| DamlType::Syn(_) => false,
}
}
fn check_tycon(&self, tycon: &DamlTyCon<'_>) -> bool {
self.check_target_data(tycon) && self.check_tycon_type_arguments(tycon)
}
fn check_target_data(&self, tycon: &DamlTyCon<'_>) -> bool {
match self.filter_mode {
RenderFilterMode::HigherKindedType => self.archive.data_by_tycon(tycon).map_or(true, |data| {
!data.type_params().iter().any(|type_var| matches!(type_var.kind(), DamlKind::Arrow(_)))
}),
RenderFilterMode::NonSerializable => self.archive.data_by_tycon(tycon).map_or(true, DamlData::serializable),
}
}
fn check_tycon_type_arguments(&self, tycon: &DamlTyCon<'_>) -> bool {
tycon.type_arguments().iter().all(|ty| self.check_type(ty))
}
}