Skip to content

Commit

Permalink
Add Iterator for KeyExpr
Browse files Browse the repository at this point in the history
  • Loading branch information
kanishk779 committed Jul 5, 2022
1 parent af960e9 commit 6b1058c
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/miniscript/musig_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,35 @@ impl<Pk: MiniscriptKey + FromStr> FromStr for KeyExpr<Pk> {
}
}

#[derive(Debug, Clone)]
/// Iterator for keyexpr
pub struct KeyExprIter<'a, Pk: MiniscriptKey> {
stack: Vec<&'a KeyExpr<Pk>>,
}

impl<'a, Pk> Iterator for KeyExprIter<'a, Pk>
where
Pk: MiniscriptKey + 'a,
{
type Item = &'a Pk;

fn next(&mut self) -> Option<Self::Item> {
while !self.stack.is_empty() {
let last = self.stack.pop().expect("Size checked above");
match &*last {
KeyExpr::MuSig(key_vec) => {
// push the elements in reverse order
for key in key_vec.iter().rev() {
self.stack.push(key)
}
}
KeyExpr::SingleKey(ref pk) => return Some(pk),
}
}
None
}
}

impl<Pk: MiniscriptKey> fmt::Debug for KeyExpr<Pk> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expand Down Expand Up @@ -79,6 +108,14 @@ impl<Pk: MiniscriptKey> fmt::Display for KeyExpr<Pk> {
}
}
}

impl<Pk: MiniscriptKey> KeyExpr<Pk> {
/// Iterate over all keys
pub fn iter(&self) -> KeyExprIter<Pk> {
KeyExprIter { stack: vec![self] }
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -97,4 +134,16 @@ mod tests {
test_one("A");
test_one("musig(,,)");
}

#[test]
fn test_iterator() {
let pk = KeyExpr::<String>::from_str("musig(A,B,musig(C,musig(D,E)))").unwrap();
let mut my_iter = pk.iter();
assert_eq!(my_iter.next(), Some(&String::from("A")));
assert_eq!(my_iter.next(), Some(&String::from("B")));
assert_eq!(my_iter.next(), Some(&String::from("C")));
assert_eq!(my_iter.next(), Some(&String::from("D")));
assert_eq!(my_iter.next(), Some(&String::from("E")));
assert_eq!(my_iter.next(), None);
}
}

0 comments on commit 6b1058c

Please sign in to comment.