use super::ProcError;
impl crate::TypeInner {
pub fn indexable_length(&self, module: &crate::Module) -> Result<IndexableLength, ProcError> {
use crate::TypeInner as Ti;
let known_length = match *self {
Ti::Vector { size, .. } => size as _,
Ti::Matrix { columns, .. } => columns as _,
Ti::Array { size, .. } => {
return size.to_indexable_length(module);
}
Ti::ValuePointer {
size: Some(size), ..
} => size as _,
Ti::Pointer { base, .. } => {
let base_inner = &module.types[base].inner;
match *base_inner {
Ti::Vector { size, .. } => size as _,
Ti::Matrix { columns, .. } => columns as _,
Ti::Array { size, .. } => return size.to_indexable_length(module),
_ => return Err(ProcError::TypeNotIndexable),
}
}
_ => return Err(ProcError::TypeNotIndexable),
};
Ok(IndexableLength::Known(known_length))
}
}
pub enum IndexableLength {
Known(u32),
Specializable(crate::Handle<crate::Constant>),
Dynamic,
}
impl crate::ArraySize {
pub fn to_indexable_length(self, module: &crate::Module) -> Result<IndexableLength, ProcError> {
use crate::Constant as K;
Ok(match self {
Self::Constant(k) => match module.constants[k] {
K {
specialization: Some(_),
..
} => IndexableLength::Specializable(k),
ref unspecialized => {
let length = unspecialized
.to_array_length()
.ok_or(ProcError::InvalidArraySizeConstant(k))?;
IndexableLength::Known(length)
}
},
Self::Dynamic => IndexableLength::Dynamic,
})
}
}