use super::*;
impl<N: Network> Plaintext<N> {
pub fn find<A: Into<Access<N>> + Copy + Debug>(&self, path: &[A]) -> Result<Plaintext<N>> {
ensure!(!path.is_empty(), "Attempted to find a member with an empty path.");
match self {
Self::Literal(..) => bail!("'{self}' is not a struct"),
Self::Struct(..) | Self::Array(..) => {
let mut plaintext = self;
for access in path.iter() {
let access = (*access).into();
match (plaintext, access) {
(Self::Struct(members, ..), Access::Member(identifier)) => {
match members.get(&identifier) {
Some(member) => plaintext = member,
None => bail!("Failed to locate member '{identifier}' in '{self}'"),
}
}
(Self::Array(array, ..), Access::Index(index)) => {
match array.get(*index as usize) {
Some(element) => plaintext = element,
None => bail!("Index '{index}' for '{self}' is out of bounds"),
}
}
_ => bail!("Invalid access `{access}` for `{plaintext}`"),
}
}
Ok(plaintext.clone())
}
}
}
}