@@ -18,6 +18,7 @@ use lightning::util::logger::Logger;
18
18
use secp256k1:: PublicKey ;
19
19
use core:: ops:: Deref ;
20
20
use core:: time:: Duration ;
21
+ use core:: iter:: Iterator ;
21
22
22
23
/// Utility to create an invoice that can be paid to one of multiple nodes, or a "phantom invoice."
23
24
/// See [`PhantomKeysManager`] for more information on phantom node payments.
@@ -292,6 +293,31 @@ where
292
293
}
293
294
}
294
295
296
+ /// Draw items iteratively from multiple iterators. The items are retrieved by index and
297
+ /// rotates through the iterators - first the zero index then the first index then second index, etc.
298
+ fn rotate_through_iterators< T , I : Iterator < Item = T > > ( mut vecs : Vec < I > ) -> impl Iterator < Item = T > {
299
+ let mut iterations = 0 ;
300
+
301
+ core:: iter:: from_fn ( move || {
302
+ let mut exhausted_iterators = 0 ;
303
+ loop {
304
+ if vecs. is_empty ( ) {
305
+ return None ;
306
+ }
307
+ let next_idx = iterations % vecs. len ( ) ;
308
+ iterations += 1 ;
309
+ if let Some ( item) = vecs[ next_idx] . next ( ) {
310
+ return Some ( item) ;
311
+ }
312
+ // exhausted_vectors increase when the "next_idx" vector is exhausted
313
+ exhausted_iterators += 1 ;
314
+ // The check for exhausted iterators gets reset to 0 after each yield of `Some()`
315
+ // The lop will return None when all of the nested iterators are exhausted
316
+ if exhausted_iterators == vecs. len ( ) {
317
+ return None ;
318
+ }
319
+ }
320
+ } )
295
321
#[ cfg( feature = "std" ) ]
296
322
/// Utility to construct an invoice. Generally, unless you want to do something like a custom
297
323
/// cltv_expiry, this is what you should be using to create an invoice. The reason being, this
@@ -777,7 +803,7 @@ mod test {
777
803
use lightning:: routing:: router:: { PaymentParameters , RouteParameters } ;
778
804
use lightning:: util:: test_utils;
779
805
use lightning:: util:: config:: UserConfig ;
780
- use crate :: utils:: create_invoice_from_channelmanager_and_duration_since_epoch;
806
+ use crate :: utils:: { create_invoice_from_channelmanager_and_duration_since_epoch, rotate_through_iterators } ;
781
807
use std:: collections:: HashSet ;
782
808
783
809
#[ test]
@@ -1886,4 +1912,111 @@ mod test {
1886
1912
_ => panic ! ( ) ,
1887
1913
}
1888
1914
}
1915
+
1916
+ #[ test]
1917
+ fn test_rotate_through_iterators ( ) {
1918
+ // two nested vectors
1919
+ let a = vec ! [ vec![ "a0" , "b0" , "c0" ] . into_iter( ) , vec![ "a1" , "b1" ] . into_iter( ) ] ;
1920
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
1921
+
1922
+ let expected = vec ! [ "a0" , "a1" , "b0" , "b1" , "c0" ] ;
1923
+ assert_eq ! ( expected, result) ;
1924
+
1925
+ // test single nested vector
1926
+ let a = vec ! [ vec![ "a0" , "b0" , "c0" ] . into_iter( ) ] ;
1927
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
1928
+
1929
+ let expected = vec ! [ "a0" , "b0" , "c0" ] ;
1930
+ assert_eq ! ( expected, result) ;
1931
+
1932
+ // test second vector with only one element
1933
+ let a = vec ! [ vec![ "a0" , "b0" , "c0" ] . into_iter( ) , vec![ "a1" ] . into_iter( ) ] ;
1934
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
1935
+
1936
+ let expected = vec ! [ "a0" , "a1" , "b0" , "c0" ] ;
1937
+ assert_eq ! ( expected, result) ;
1938
+
1939
+ // test three nestend vectors
1940
+ let a = vec ! [ vec![ "a0" ] . into_iter( ) , vec![ "a1" , "b1" , "c1" ] . into_iter( ) , vec![ "a2" ] . into_iter( ) ] ;
1941
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
1942
+
1943
+ let expected = vec ! [ "a0" , "a1" , "a2" , "b1" , "c1" ] ;
1944
+ assert_eq ! ( expected, result) ;
1945
+
1946
+ // test single nested vector with a single value
1947
+ let a = vec ! [ vec![ "a0" ] . into_iter( ) ] ;
1948
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
1949
+
1950
+ let expected = vec ! [ "a0" ] ;
1951
+ assert_eq ! ( expected, result) ;
1952
+
1953
+ // test single empty nested vector
1954
+ let a: Vec < std:: vec:: IntoIter < & str > > = vec ! [ vec![ ] . into_iter( ) ] ;
1955
+ let result = rotate_through_iterators ( a) . collect :: < Vec < & str > > ( ) ;
1956
+ let expected: Vec < & str > = vec ! [ ] ;
1957
+
1958
+ assert_eq ! ( expected, result) ;
1959
+
1960
+ // test first nested vector is empty
1961
+ let a: Vec < std:: vec:: IntoIter < & str > > = vec ! [ vec![ ] . into_iter( ) , vec![ "a1" , "b1" , "c1" ] . into_iter( ) ] ;
1962
+ let result = rotate_through_iterators ( a) . collect :: < Vec < & str > > ( ) ;
1963
+
1964
+ let expected = vec ! [ "a1" , "b1" , "c1" ] ;
1965
+ assert_eq ! ( expected, result) ;
1966
+
1967
+ // test two empty vectors
1968
+ let a: Vec < std:: vec:: IntoIter < & str > > = vec ! [ vec![ ] . into_iter( ) , vec![ ] . into_iter( ) ] ;
1969
+ let result = rotate_through_iterators ( a) . collect :: < Vec < & str > > ( ) ;
1970
+
1971
+ let expected: Vec < & str > = vec ! [ ] ;
1972
+ assert_eq ! ( expected, result) ;
1973
+
1974
+ // test an empty vector amongst other filled vectors
1975
+ let a = vec ! [
1976
+ vec![ "a0" , "b0" , "c0" ] . into_iter( ) ,
1977
+ vec![ ] . into_iter( ) ,
1978
+ vec![ "a1" , "b1" , "c1" ] . into_iter( ) ,
1979
+ vec![ "a2" , "b2" , "c2" ] . into_iter( ) ,
1980
+ ] ;
1981
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
1982
+
1983
+ let expected = vec ! [ "a0" , "a1" , "a2" , "b0" , "b1" , "b2" , "c0" , "c1" , "c2" ] ;
1984
+ assert_eq ! ( expected, result) ;
1985
+
1986
+ // test a filled vector between two empty vectors
1987
+ let a = vec ! [ vec![ ] . into_iter( ) , vec![ "a1" , "b1" , "c1" ] . into_iter( ) , vec![ ] . into_iter( ) ] ;
1988
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
1989
+
1990
+ let expected = vec ! [ "a1" , "b1" , "c1" ] ;
1991
+ assert_eq ! ( expected, result) ;
1992
+
1993
+ // test an empty vector at the end of the vectors
1994
+ let a = vec ! [ vec![ "a0" , "b0" , "c0" ] . into_iter( ) , vec![ ] . into_iter( ) ] ;
1995
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
1996
+
1997
+ let expected = vec ! [ "a0" , "b0" , "c0" ] ;
1998
+ assert_eq ! ( expected, result) ;
1999
+
2000
+ // test multiple empty vectors amongst multiple filled vectors
2001
+ let a = vec ! [
2002
+ vec![ ] . into_iter( ) ,
2003
+ vec![ "a1" , "b1" , "c1" ] . into_iter( ) ,
2004
+ vec![ ] . into_iter( ) ,
2005
+ vec![ "a3" , "b3" ] . into_iter( ) ,
2006
+ vec![ ] . into_iter( ) ,
2007
+ ] ;
2008
+
2009
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
2010
+
2011
+ let expected = vec ! [ "a1" , "a3" , "b1" , "b3" , "c1" ] ;
2012
+ assert_eq ! ( expected, result) ;
2013
+
2014
+ // test one element in the first nested vectore and two elements in the second nested
2015
+ // vector
2016
+ let a = vec ! [ vec![ "a0" ] . into_iter( ) , vec![ "a1" , "b1" ] . into_iter( ) ] ;
2017
+ let result = rotate_through_iterators ( a) . collect :: < Vec < _ > > ( ) ;
2018
+
2019
+ let expected = vec ! [ "a0" , "a1" , "b1" ] ;
2020
+ assert_eq ! ( expected, result) ;
2021
+ }
1889
2022
}
0 commit comments