use super::{Cluster, Register};
#[cfg_attr(
feature = "serde",
derive(serde::Deserialize, serde::Serialize),
serde(rename_all = "lowercase")
)]
#[derive(Clone, Debug, PartialEq)]
#[allow(clippy::large_enum_variant)]
pub enum RegisterCluster {
Register(Register),
Cluster(Cluster),
}
impl From<Register> for RegisterCluster {
fn from(reg: Register) -> Self {
Self::Register(reg)
}
}
impl From<Cluster> for RegisterCluster {
fn from(cluser: Cluster) -> Self {
Self::Cluster(cluser)
}
}
impl RegisterCluster {
pub fn name(&self) -> &String {
match self {
Self::Register(r) => &r.name,
Self::Cluster(c) => &c.name,
}
}
pub fn description(&self) -> &Option<String> {
match self {
Self::Register(r) => &r.description,
Self::Cluster(c) => &c.description,
}
}
pub fn derived_from(&self) -> &Option<String> {
match self {
Self::Register(r) => &r.derived_from,
Self::Cluster(c) => &c.derived_from,
}
}
pub fn address_offset(&self) -> u32 {
match self {
Self::Register(r) => r.address_offset,
Self::Cluster(c) => c.address_offset,
}
}
}
pub struct RegisterIter<'a> {
pub(crate) all: std::slice::Iter<'a, RegisterCluster>,
}
impl<'a> std::iter::Iterator for RegisterIter<'a> {
type Item = &'a Register;
fn next(&mut self) -> Option<Self::Item> {
match self.all.next() {
None => None,
Some(RegisterCluster::Register(reg)) => Some(reg),
_ => self.next(),
}
}
}
pub struct RegisterIterMut<'a> {
pub(crate) all: std::slice::IterMut<'a, RegisterCluster>,
}
impl<'a> std::iter::Iterator for RegisterIterMut<'a> {
type Item = &'a mut Register;
fn next(&mut self) -> Option<Self::Item> {
match self.all.next() {
None => None,
Some(RegisterCluster::Register(reg)) => Some(reg),
_ => self.next(),
}
}
}
pub struct ClusterIter<'a> {
pub(crate) all: std::slice::Iter<'a, RegisterCluster>,
}
impl<'a> std::iter::Iterator for ClusterIter<'a> {
type Item = &'a Cluster;
fn next(&mut self) -> Option<Self::Item> {
match self.all.next() {
None => None,
Some(RegisterCluster::Cluster(c)) => Some(c),
_ => self.next(),
}
}
}
pub struct ClusterIterMut<'a> {
pub(crate) all: std::slice::IterMut<'a, RegisterCluster>,
}
impl<'a> std::iter::Iterator for ClusterIterMut<'a> {
type Item = &'a mut Cluster;
fn next(&mut self) -> Option<Self::Item> {
match self.all.next() {
None => None,
Some(RegisterCluster::Cluster(c)) => Some(c),
_ => self.next(),
}
}
}
pub struct AllRegistersIter<'a> {
pub(crate) rem: Vec<&'a RegisterCluster>,
}
impl<'a> std::iter::Iterator for AllRegistersIter<'a> {
type Item = &'a Register;
fn next(&mut self) -> Option<Self::Item> {
while let Some(b) = self.rem.pop() {
match b {
RegisterCluster::Register(reg) => {
return Some(reg);
}
RegisterCluster::Cluster(cluster) => {
for c in cluster.children.iter().rev() {
self.rem.push(c);
}
}
}
}
None
}
}
pub struct AllRegistersIterMut<'a> {
pub(crate) rem: Vec<&'a mut RegisterCluster>,
}
impl<'a> std::iter::Iterator for AllRegistersIterMut<'a> {
type Item = &'a mut Register;
fn next(&mut self) -> Option<Self::Item> {
while let Some(b) = self.rem.pop() {
match b {
RegisterCluster::Register(reg) => {
return Some(reg);
}
RegisterCluster::Cluster(cluster) => {
for c in cluster.children.iter_mut().rev() {
self.rem.push(c);
}
}
}
}
None
}
}