use std::collections::BTreeSet;
use crate::wir::{WIdent, WItemFn, YConverted, YStage};
#[derive(Clone, Debug, Hash)]
pub struct WProperty<Y: YStage> {
pub subproperties: Vec<WSubproperty<Y>>,
}
#[derive(Clone, Debug, Hash)]
pub enum WSubproperty<Y: YStage> {
Func(WSubpropertyFunc<Y>),
FixedPoint(WSubpropertyFixedPoint),
Next(WSubpropertyNext),
}
#[derive(Clone, Debug, Hash)]
pub struct WSubpropertyFunc<Y: YStage> {
pub parent: Option<usize>,
pub func: WItemFn<Y>,
pub children: Vec<usize>,
pub display: Option<String>,
}
#[derive(Clone, Debug, Hash)]
pub struct WSubpropertyFixedPoint {
pub parent: Option<usize>,
pub greatest: bool,
pub variable: WIdent,
pub inner: usize,
pub display: Option<String>,
}
#[derive(Clone, Debug, Hash)]
pub struct WSubpropertyNext {
pub parent: Option<usize>,
pub universal: bool,
pub inner: usize,
pub display: Option<String>,
}
impl<Y: YStage> WSubproperty<Y> {
pub fn children(&self) -> &[usize] {
match self {
WSubproperty::Func(subprop) => &subprop.children,
WSubproperty::FixedPoint(fixed_point) => std::slice::from_ref(&fixed_point.inner),
WSubproperty::Next(next) => std::slice::from_ref(&next.inner),
}
}
}
impl WSubproperty<YConverted> {
pub fn dependencies(&self) -> BTreeSet<usize> {
match self {
WSubproperty::Func(subprop) => {
let mut dependencies = BTreeSet::new();
for input_arg in &subprop.func.signature.inputs {
let input_var_name = input_arg.ident.name();
if let Some(stripped) = input_var_name.strip_prefix("__mck_subproperty_") {
let Ok(input_subproperty_index) = stripped.parse::<usize>() else {
panic!("Input subproperty should have valid index");
};
dependencies.insert(input_subproperty_index);
}
}
dependencies
}
WSubproperty::FixedPoint(fixed_point) => BTreeSet::from([fixed_point.inner]),
WSubproperty::Next(next) => BTreeSet::from([next.inner]),
}
}
}
pub trait IntoSyn<T> {
fn into_syn(self) -> T;
}